// Copyright (c) 2012 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 SHILL_POWER_MANAGER_H_
#define SHILL_POWER_MANAGER_H_

// This class instantiates a PowerManagerProxy and distributes power events to
// registered users.  It also provides a means for calling methods on the
// PowerManagerProxy.
//
// Usage:
//
// Registering for power state changes is done as follows:
//
//   class Foo {
//    public:
//     void HandleStateChange(PowerManager::SuspendState new_state);
//   };
//   Foo foo;
//   PowerManager power_manager(ProxyFactory::GetInstance());
//   PowerManager::PowerStateCallback cb = Bind(&Foo::HandleStateChange, &foo);
//   power_manager.AddStateChangeCallback("foo_key", cb);
//
//   Note that depending on the definition of Foo, "&foo" may need to appear
//   inside an appropriate wrapper, such as base::Unretained.
//
// Whenever the power state changes, foo.HandleStateChange() is called with the
// new state passed in. To unregister:
//
//   power_manager.RemoveStateChangeCallback("foo_key");

#include <map>
#include <string>

#include <base/callback.h>
#include <base/cancelable_callback.h>
#include <base/memory/scoped_ptr.h>

#include "shill/power_manager_proxy_interface.h"

namespace shill {

class EventDispatcher;
class ProxyFactory;

class PowerManager : public PowerManagerProxyDelegate {
 public:
  typedef PowerManagerProxyDelegate::SuspendState SuspendState;

  // Callbacks registered with the power manager are of this type.  They take
  // one argument, the new power state.  The callback function or method should
  // look like this:
  //
  //   void HandlePowerStateChange(PowerStateCallbacks::SuspendState);
  typedef base::Callback<void(SuspendState)> PowerStateCallback;

  // This callback is called prior to a suspend event.  When it is OK for the
  // system to suspend, this callback should call ReportSuspendReadiness(),
  // passing it the suspend ID passed to this callback.
  typedef base::Callback<void(int)> SuspendDelayCallback;

  static const int kSuspendTimeoutMilliseconds;

  // |proxy_factory| creates the PowerManagerProxy.  Usually this is
  // ProxyFactory::GetInstance().  Use a fake for testing.
  PowerManager(EventDispatcher *dispatcher,
               ProxyFactory *proxy_factory);
  virtual ~PowerManager();

  SuspendState power_state() const { return power_state_; }

  // Methods inherited from PowerManagerProxyDelegate.
  virtual void OnSuspendImminent(int suspend_id);
  virtual void OnPowerStateChanged(SuspendState new_power_state);

  // See corresponding methods in PowerManagerProxyInterface.
  virtual bool RegisterSuspendDelay(base::TimeDelta timeout,
                                    const std::string &description,
                                    int *delay_id_out);
  virtual bool UnregisterSuspendDelay(int delay_id);
  virtual bool ReportSuspendReadiness(int delay_id, int suspend_id);

  // Registers a power state change callback with the power manager.  When a
  // power state change occurs, this callback will be called with the new power
  // state as its argument.  |key| must be unique.
  virtual void AddStateChangeCallback(const std::string &key,
                                      const PowerStateCallback &callback);

  // Registers a suspend delay callback with the power manager.  This callback
  // will be called prior to a suspend event by the amount specified in the most
  // recent call to RegisterSuspendDelay().  |key| must be unique.
  virtual void AddSuspendDelayCallback(const std::string &key,
                                       const SuspendDelayCallback &callback);

  // Unregisters a power state change callback identified by |key|.  The
  // callback must have been previously registered and not yet removed.
  virtual void RemoveStateChangeCallback(const std::string &key);

  // Unregisters a suspend delay callback identified by |key|.  The callback
  // must have been previously registered and not yet removed.
  virtual void RemoveSuspendDelayCallback(const std::string &key);

 private:
  friend class ManagerTest;
  friend class PowerManagerTest;
  friend class ServiceTest;

  typedef std::map<const std::string, PowerStateCallback>
    StateChangeCallbackMap;

  typedef std::map<const std::string, SuspendDelayCallback>
    SuspendDelayCallbackMap;

  void OnSuspendTimeout();

  template<class Callback>
  void AddCallback(const std::string &key, const Callback &callback,
                   std::map<const std::string, Callback> *callback_map);

  template<class Callback>
  void RemoveCallback(const std::string &key,
                      std::map<const std::string, Callback> *callback_map);

  template<class Param, class Callback>
  void OnEvent(const Param &param,
               std::map<const std::string, Callback> *callback_map) const;

  EventDispatcher *dispatcher_;

  // The power manager proxy created by this class.  It dispatches the inherited
  // delegate methods of this object when changes in the power state occur.
  const scoped_ptr<PowerManagerProxyInterface> power_manager_proxy_;
  StateChangeCallbackMap state_change_callbacks_;
  SuspendDelayCallbackMap suspend_delay_callbacks_;
  base::CancelableClosure suspend_timeout_;

  SuspendState power_state_;

  DISALLOW_COPY_AND_ASSIGN(PowerManager);
};

}  // namespace shill

#endif  // SHILL_POWER_MANAGER_H_
