// Copyright (c) 2013 The Chromium 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 DBUS_OBJECT_MANAGER_H_
#define DBUS_OBJECT_MANAGER_H_

#include <stdint.h>

#include <map>

#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "dbus/object_path.h"
#include "dbus/property.h"

// Newer D-Bus services implement the Object Manager interface to inform other
// clients about the objects they export, the properties of those objects, and
// notification of changes in the set of available objects:
//     http://dbus.freedesktop.org/doc/dbus-specification.html
//       #standard-interfaces-objectmanager
//
// This interface is very closely tied to the Properties interface, and uses
// even more levels of nested dictionaries and variants. In addition to
// simplifying implementation, since there tends to be a single object manager
// per service, spanning the complete set of objects an interfaces available,
// the classes implemented here make dealing with this interface simpler.
//
// Except where noted, use of this class replaces the need for the code
// documented in dbus/property.h
//
// Client implementation classes should begin by deriving from the
// dbus::ObjectManager::Interface class, and defining a Properties structure as
// documented in dbus/property.h.
//
// Example:
//   class ExampleClient : public dbus::ObjectManager::Interface {
//    public:
//     struct Properties : public dbus::PropertySet {
//       dbus::Property<std::string> name;
//       dbus::Property<uint16_t> version;
//       dbus::Property<dbus::ObjectPath> parent;
//       dbus::Property<std::vector<std::string>> children;
//
//       Properties(dbus::ObjectProxy* object_proxy,
//                  const PropertyChangedCallback callback)
//           : dbus::PropertySet(object_proxy, kExampleInterface, callback) {
//         RegisterProperty("Name", &name);
//         RegisterProperty("Version", &version);
//         RegisterProperty("Parent", &parent);
//         RegisterProperty("Children", &children);
//       }
//       virtual ~Properties() {}
//     };
//
// The link between the implementation class and the object manager is set up
// in the constructor and removed in the destructor; the class should maintain
// a pointer to its object manager for use in other methods and establish
// itself as the implementation class for its interface.
//
// Example:
//   explicit ExampleClient::ExampleClient(dbus::Bus* bus)
//       : bus_(bus),
//         weak_ptr_factory_(this) {
//     object_manager_ = bus_->GetObjectManager(kServiceName, kManagerPath);
//     object_manager_->RegisterInterface(kInterface, this);
//   }
//
//   virtual ExampleClient::~ExampleClient() {
//     object_manager_->UnregisterInterface(kInterface);
//   }
//
// This class calls GetManagedObjects() asynchronously after the remote service
// becomes available and additionally refreshes managed objects after the
// service stops or restarts.
//
// The object manager interface class has one abstract method that must be
// implemented by the class to create Properties structures on demand. As well
// as implementing this, you will want to implement a public GetProperties()
// method.
//
// Example:
//   dbus::PropertySet* CreateProperties(dbus::ObjectProxy* object_proxy,
//                                       const std::string& interface_name)
//       override {
//     Properties* properties = new Properties(
//           object_proxy, interface_name,
//           base::Bind(&PropertyChanged,
//                      weak_ptr_factory_.GetWeakPtr(),
//                      object_path));
//     return static_cast<dbus::PropertySet*>(properties);
//   }
//
//   Properties* GetProperties(const dbus::ObjectPath& object_path) {
//     return static_cast<Properties*>(
//         object_manager_->GetProperties(object_path, kInterface));
//   }
//
// Note that unlike classes that only use dbus/property.h there is no need
// to connect signals or obtain the initial values of properties. The object
// manager class handles that for you.
//
// PropertyChanged is a method of your own to notify your observers of a change
// in your properties, either as a result of a signal from the Properties
// interface or from the Object Manager interface. You may also wish to
// implement the optional ObjectAdded and ObjectRemoved methods of the class
// to likewise notify observers.
//
// When your class needs an object proxy for a given object path, it may
// obtain it from the object manager. Unlike the equivalent method on the bus
// this will return NULL if the object is not known.
//
//   object_proxy = object_manager_->GetObjectProxy(object_path);
//   if (object_proxy) {
//     ...
//   }
//
// There is no need for code using your implementation class to be aware of the
// use of object manager behind the scenes, the rules for updating properties
// documented in dbus/property.h still apply.

namespace dbus {

const char kObjectManagerInterface[] = "org.freedesktop.DBus.ObjectManager";
const char kObjectManagerGetManagedObjects[] = "GetManagedObjects";
const char kObjectManagerInterfacesAdded[] = "InterfacesAdded";
const char kObjectManagerInterfacesRemoved[] = "InterfacesRemoved";

class Bus;
class MessageReader;
class ObjectProxy;
class Response;
class Signal;

// ObjectManager implements both the D-Bus client components of the D-Bus
// Object Manager interface, as internal methods, and a public API for
// client classes to utilize.
class CHROME_DBUS_EXPORT ObjectManager
    : public base::RefCountedThreadSafe<ObjectManager> {
public:
  // ObjectManager::Interface must be implemented by any class wishing to have
  // its remote objects managed by an ObjectManager.
  class Interface {
   public:
    virtual ~Interface() {}

    // Called by ObjectManager to create a Properties structure for the remote
    // D-Bus object identified by |object_path| and accessibile through
    // |object_proxy|. The D-Bus interface name |interface_name| is that passed
    // to RegisterInterface() by the implementation class.
    //
    // The implementation class should create and return an instance of its own
    // subclass of dbus::PropertySet; ObjectManager will then connect signals
    // and update the properties from its own internal message reader.
    virtual PropertySet* CreateProperties(
        ObjectProxy *object_proxy,
        const dbus::ObjectPath& object_path,
        const std::string& interface_name) = 0;

    // Called by ObjectManager to inform the implementation class that an
    // object has been added with the path |object_path|. The D-Bus interface
    // name |interface_name| is that passed to RegisterInterface() by the
    // implementation class.
    //
    // If a new object implements multiple interfaces, this method will be
    // called on each interface implementation with differing values of
    // |interface_name| as appropriate. An implementation class will only
    // receive multiple calls if it has registered for multiple interfaces.
    virtual void ObjectAdded(const ObjectPath& object_path,
                             const std::string& interface_name) { }

    // Called by ObjectManager to inform the implementation class than an
    // object with the path |object_path| has been removed. Ths D-Bus interface
    // name |interface_name| is that passed to RegisterInterface() by the
    // implementation class. Multiple interfaces are handled as with
    // ObjectAdded().
    //
    // This method will be called before the Properties structure and the
    // ObjectProxy object for the given interface are cleaned up, it is safe
    // to retrieve them during removal to vary processing.
    virtual void ObjectRemoved(const ObjectPath& object_path,
                               const std::string& interface_name) { }
  };

  // Client code should use Bus::GetObjectManager() instead of this constructor.
  ObjectManager(Bus* bus,
                const std::string& service_name,
                const ObjectPath& object_path);

  // Register a client implementation class |interface| for the given D-Bus
  // interface named in |interface_name|. That object's CreateProperties()
  // method will be used to create instances of dbus::PropertySet* when
  // required.
  virtual void RegisterInterface(const std::string& interface_name,
                                 Interface* interface);

  // Unregister the implementation class for the D-Bus interface named in
  // |interface_name|, objects and properties of this interface will be
  // ignored.
  virtual void UnregisterInterface(const std::string& interface_name);

  // Returns a list of object paths, in an undefined order, of objects known
  // to this manager.
  virtual std::vector<ObjectPath> GetObjects();

  // Returns the list of object paths, in an undefined order, of objects
  // implementing the interface named in |interface_name| known to this manager.
  virtual std::vector<ObjectPath> GetObjectsWithInterface(
      const std::string& interface_name);

  // Returns a ObjectProxy pointer for the given |object_path|. Unlike
  // the equivalent method on Bus this will return NULL if the object
  // manager has not been informed of that object's existence.
  virtual ObjectProxy* GetObjectProxy(const ObjectPath& object_path);

  // Returns a PropertySet* pointer for the given |object_path| and
  // |interface_name|, or NULL if the object manager has not been informed of
  // that object's existence or the interface's properties. The caller should
  // cast the returned pointer to the appropriate type, e.g.:
  //   static_cast<Properties*>(GetProperties(object_path, my_interface));
  virtual PropertySet* GetProperties(const ObjectPath& object_path,
                                     const std::string& interface_name);

  // Instructs the object manager to refresh its list of managed objects;
  // automatically called by the D-Bus thread manager, there should never be
  // a need to call this manually.
  void GetManagedObjects();

  // Cleans up any match rules and filter functions added by this ObjectManager.
  // The Bus object will take care of this so you don't have to do it manually.
  //
  // BLOCKING CALL.
  void CleanUp();

 protected:
  virtual ~ObjectManager();

 private:
  friend class base::RefCountedThreadSafe<ObjectManager>;

  // Called from the constructor to add a match rule for PropertiesChanged
  // signals on the D-Bus thread and set up a corresponding filter function.
  bool SetupMatchRuleAndFilter();

  // Called on the origin thread once the match rule and filter have been set
  // up. Connects the InterfacesAdded and InterfacesRemoved signals and
  // refreshes objects if the service is available. |success| is false if an
  // error occurred during setup and true otherwise.
  void OnSetupMatchRuleAndFilterComplete(bool success);

  // Called by dbus:: when a message is received. This is used to filter
  // PropertiesChanged signals from the correct sender and relay the event to
  // the correct PropertySet.
  static DBusHandlerResult HandleMessageThunk(DBusConnection* connection,
                                              DBusMessage* raw_message,
                                              void* user_data);
  DBusHandlerResult HandleMessage(DBusConnection* connection,
                                  DBusMessage* raw_message);

  // Called when a PropertiesChanged signal is received from the sender.
  // This method notifies the relevant PropertySet that it should update its
  // properties based on the received signal. Called from HandleMessage.
  void NotifyPropertiesChanged(const dbus::ObjectPath object_path,
                               Signal* signal);
  void NotifyPropertiesChangedHelper(const dbus::ObjectPath object_path,
                                     Signal* signal);

  // Called by dbus:: in response to the GetManagedObjects() method call.
  void OnGetManagedObjects(Response* response);

  // Called by dbus:: when an InterfacesAdded signal is received and initially
  // connected.
  void InterfacesAddedReceived(Signal* signal);
  void InterfacesAddedConnected(const std::string& interface_name,
                                const std::string& signal_name,
                                bool success);

  // Called by dbus:: when an InterfacesRemoved signal is received and
  // initially connected.
  void InterfacesRemovedReceived(Signal* signal);
  void InterfacesRemovedConnected(const std::string& interface_name,
                                  const std::string& signal_name,
                                  bool success);

  // Updates the map entry for the object with path |object_path| using the
  // D-Bus message in |reader|, which should consist of an dictionary mapping
  // interface names to properties dictionaries as recieved by both the
  // GetManagedObjects() method return and the InterfacesAdded() signal.
  void UpdateObject(const ObjectPath& object_path, MessageReader* reader);

  // Updates the properties structure of the object with path |object_path|
  // for the interface named |interface_name| using the D-Bus message in
  // |reader| which should consist of the properties dictionary for that
  // interface.
  //
  // Called by UpdateObjects() for each interface in the dictionary; this
  // method takes care of both creating the entry in the ObjectMap and
  // ObjectProxy if required, as well as the PropertySet instance for that
  // interface if necessary.
  void AddInterface(const ObjectPath& object_path,
                    const std::string& interface_name,
                    MessageReader* reader);

  // Removes the properties structure of the object with path |object_path|
  // for the interfaces named |interface_name|.
  //
  // If no further interfaces remain, the entry in the ObjectMap is discarded.
  void RemoveInterface(const ObjectPath& object_path,
                       const std::string& interface_name);

  // Removes all objects and interfaces from the object manager when
  // |old_owner| is not the empty string and/or re-requests the set of managed
  // objects when |new_owner| is not the empty string.
  void NameOwnerChanged(const std::string& old_owner,
                        const std::string& new_owner);

  Bus* bus_;
  std::string service_name_;
  std::string service_name_owner_;
  std::string match_rule_;
  ObjectPath object_path_;
  ObjectProxy* object_proxy_;
  bool setup_success_;
  bool cleanup_called_;

  // Maps the name of an interface to the implementation class used for
  // instantiating PropertySet structures for that interface's properties.
  typedef std::map<std::string, Interface*> InterfaceMap;
  InterfaceMap interface_map_;

  // Each managed object consists of a ObjectProxy used to make calls
  // against that object and a collection of D-Bus interface names and their
  // associated PropertySet structures.
  struct Object {
    Object();
    ~Object();

    ObjectProxy* object_proxy;

    // Maps the name of an interface to the specific PropertySet structure
    // of that interface's properties.
    typedef std::map<const std::string, PropertySet*> PropertiesMap;
    PropertiesMap properties_map;
  };

  // Maps the object path of an object to the Object structure.
  typedef std::map<const ObjectPath, Object*> ObjectMap;
  ObjectMap object_map_;

  // Weak pointer factory for generating 'this' pointers that might live longer
  // than we do.
  // Note: This should remain the last member so it'll be destroyed and
  // invalidate its weak pointers before any other members are destroyed.
  base::WeakPtrFactory<ObjectManager> weak_ptr_factory_;

  DISALLOW_COPY_AND_ASSIGN(ObjectManager);
};

}  // namespace dbus

#endif  // DBUS_OBJECT_MANAGER_H_
