// Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef LOGIN_MANAGER_SESSION_MANAGER_DBUS_ADAPTOR_H_
#define LOGIN_MANAGER_SESSION_MANAGER_DBUS_ADAPTOR_H_

#include <map>
#include <string>
#include <vector>

#include <base/basictypes.h>
#include <base/callback_forward.h>
#include <base/memory/scoped_ptr.h>
#include <dbus/exported_object.h>  // For ResponseSender.

namespace dbus {
class MethodCall;
class ObjectProxy;
class Response;
}  // namespace dbus

namespace login_manager {
class SessionManagerImpl;

// Implements the DBus SessionManagerInterface.
//
// All signatures used in the methods of the ownership API are
// SHA1 with RSA encryption.
class SessionManagerDBusAdaptor {
 public:
  explicit SessionManagerDBusAdaptor(SessionManagerImpl* impl);
  virtual ~SessionManagerDBusAdaptor();

  void ExportDBusMethods(dbus::ExportedObject* object);

  //////////////////////////////////////////////////////////////////////////////
  // Methods exposed via RPC are defined below.
  // Explanatory comments are in session_manager.xml
  scoped_ptr<dbus::Response> EmitLoginPromptVisible(dbus::MethodCall* call);
  scoped_ptr<dbus::Response> EnableChromeTesting(dbus::MethodCall* call);

  scoped_ptr<dbus::Response> StartSession(dbus::MethodCall* call);
  scoped_ptr<dbus::Response> StopSession(dbus::MethodCall* call);

  // Asynchronous.
  void StorePolicy(dbus::MethodCall* call,
                   dbus::ExportedObject::ResponseSender sender);
  scoped_ptr<dbus::Response> RetrievePolicy(dbus::MethodCall* call);

  // Asynchronous.
  void StorePolicyForUser(dbus::MethodCall* call,
                          dbus::ExportedObject::ResponseSender sender);
  scoped_ptr<dbus::Response> RetrievePolicyForUser(dbus::MethodCall* call);

  // Asynchronous.
  void StoreDeviceLocalAccountPolicy(
      dbus::MethodCall* call,
      dbus::ExportedObject::ResponseSender sender);
  scoped_ptr<dbus::Response> RetrieveDeviceLocalAccountPolicy(
      dbus::MethodCall* call);

  scoped_ptr<dbus::Response> RetrieveSessionState(dbus::MethodCall* call);
  scoped_ptr<dbus::Response> RetrieveActiveSessions(dbus::MethodCall* call);

  scoped_ptr<dbus::Response> LockScreen(dbus::MethodCall* call);
  scoped_ptr<dbus::Response> HandleLockScreenShown(dbus::MethodCall* call);
  scoped_ptr<dbus::Response> HandleLockScreenDismissed(dbus::MethodCall* call);

  scoped_ptr<dbus::Response> RestartJob(dbus::MethodCall* call);
  scoped_ptr<dbus::Response> StartDeviceWipe(dbus::MethodCall* call);
  scoped_ptr<dbus::Response> SetFlagsForUser(dbus::MethodCall* call);

  scoped_ptr<dbus::Response> Introspect(dbus::MethodCall* call);

 private:
  // Pointer to a member function for handling a DBus method call.
  typedef scoped_ptr<dbus::Response> (
      SessionManagerDBusAdaptor::*SyncDBusMethodCallMemberFunction)(
          dbus::MethodCall*);
  // Pointer to a member function for handling an async DBus method call.
  typedef void (SessionManagerDBusAdaptor::*AsyncDBusMethodCallMemberFunction)(
      dbus::MethodCall*,
      dbus::ExportedObject::ResponseSender);

  void ExportSyncDBusMethod(dbus::ExportedObject* object,
                            const std::string& method_name,
                            SyncDBusMethodCallMemberFunction member);
  void ExportAsyncDBusMethod(dbus::ExportedObject* object,
                             const std::string& method_name,
                             AsyncDBusMethodCallMemberFunction member);

  SessionManagerImpl* const impl_;

  DISALLOW_COPY_AND_ASSIGN(SessionManagerDBusAdaptor);
};

}  // namespace login_manager
#endif  // LOGIN_MANAGER_SESSION_MANAGER_DBUS_ADAPTOR_H_
