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

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

#include "base/basictypes.h"
#include "base/bind.h"
#include "base/callback.h"
#include "dbus/dbus_export.h"
#include "dbus/message.h"
#include "dbus/object_proxy.h"

// D-Bus objects frequently provide sets of properties accessed via a
// standard interface of method calls and signals to obtain the current value,
// set a new value and be notified of changes to the value. Unfortunately this
// interface makes heavy use of variants and dictionaries of variants. The
// classes defined here make dealing with properties in a type-safe manner
// possible.
//
// Client implementation classes should define a Properties structure, deriving
// from the PropertySet class defined here. This structure should contain a
// member for each property defined as an instance of the Property<> class,
// specifying the type to the template. Finally the structure should chain up
// to the PropertySet constructor, and then call RegisterProperty() for each
// property defined to associate them with their string name.
//
// Example:
//   class ExampleClient {
//    public:
//     struct Properties : public dbus::PropertySet {
//       dbus::Property<std::string> name;
//       dbus::Property<uint16> 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, "com.example.DBus", callback) {
//         RegisterProperty("Name", &name);
//         RegisterProperty("Version", &version);
//         RegisterProperty("Parent", &parent);
//         RegisterProperty("Children", &children);
//       }
//       virtual ~Properties() {}
//     };
//
// The Properties structure requires a pointer to the object proxy of the
// actual object to track, and after construction should have signals
// connected to that object and initial values set by calling ConnectSignals()
// and GetAll(). The structure should not outlive the object proxy, so it
// is recommended that the lifecycle of both be managed together.
//
// Example (continued):
//
//     typedef std::map<std::pair<dbus::ObjectProxy*, Properties*> > Object;
//     typedef std::map<dbus::ObjectPath, Object> ObjectMap;
//     ObjectMap object_map_;
//
//     dbus::ObjectProxy* GetObjectProxy(const dbus::ObjectPath& object_path) {
//       return GetObject(object_path).first;
//     }
//
//     Properties* GetProperties(const dbus::ObjectPath& object_path) {
//       return GetObject(object_path).second;
//     }
//
//     Object GetObject(const dbus::ObjectPath& object_path) {
//       ObjectMap::iterator it = object_map_.find(object_path);
//       if (it != object_map_.end())
//         return it->second;
//
//       dbus::ObjectProxy* object_proxy = bus->GetObjectProxy(...);
//       // connect signals, etc.
//
//       Properties* properties = new Properties(
//           object_proxy,
//           base::Bind(&PropertyChanged,
//                      weak_ptr_factory_.GetWeakPtr(),
//                      object_path));
//       properties->ConnectSignals();
//       properties->GetAll();
//
//       Object object = std::make_pair(object_proxy, properties);
//       object_map_[object_path] = object;
//       return object;
//     }
//  };
//
// This now allows code using the client implementation to access properties
// in a type-safe manner, and assuming the PropertyChanged callback is
// propogated up to observers, be notified of changes. A typical access of
// the current value of the name property would be:
//
//   ExampleClient::Properties* p = example_client->GetProperties(object_path);
//   std::string name = p->name.value();
//
// Normally these values are updated from signals emitted by the remote object,
// in case an explicit round-trip is needed to obtain the current value, the
// Get() method can be used and indicates whether or not the value update was
// successful. The updated value can be obtained in the callback using the
// value() method.
//
//   p->children.Get(base::Bind(&OnGetChildren));
//
// A new value can be set using the Set() method, the callback indicates
// success only; it is up to the remote object when (and indeed if) it updates
// the property value, and whether it emits a signal or a Get() call is
// required to obtain it.
//
//   p->version.Set(20, base::Bind(&OnSetVersion))

namespace dbus {

// D-Bus Properties interface constants, declared here rather than
// in property.cc because template methods use them.
const char kPropertiesInterface[] = "org.freedesktop.DBus.Properties";
const char kPropertiesGetAll[] = "GetAll";
const char kPropertiesGet[] = "Get";
const char kPropertiesSet[] = "Set";
const char kPropertiesChanged[] = "PropertiesChanged";

class PropertySet;

// PropertyBase is an abstract base-class consisting of the parts of
// the Property<> template that are not type-specific, such as the
// associated PropertySet, property name, and the type-unsafe parts
// used by PropertySet.
class PropertyBase {
 public:
  PropertyBase() : property_set_(NULL) {}

  // Initializes the |property_set| and property |name| so that method
  // calls may be made from this class. This method is called by
  // PropertySet::RegisterProperty() passing |this| for |property_set| so
  // there should be no need to call it directly. If you do beware that
  // no ownership or reference to |property_set| is taken so that object
  // must outlive this one.
  void Init(PropertySet* property_set, const std::string& name);

  // Retrieves the name of this property, this may be useful in observers
  // to avoid specifying the name in more than once place, e.g.
  //
  //   void Client::PropertyChanged(const dbus::ObjectPath& object_path,
  //                                const std::string &property_name) {
  //     Properties& properties = GetProperties(object_path);
  //     if (property_name == properties.version.name()) {
  //       // Handle version property changing
  //     }
  //   }
  const std::string& name() const { return name_; }

  // Method used by PropertySet to retrieve the value from a MessageReader,
  // no knowledge of the contained type is required, this method returns
  // true if its expected type was found, false if not.
  // Implementation provided by specialization.
  virtual bool PopValueFromReader(MessageReader* reader) = 0;

  // Method used by PropertySet to append the set value to a MessageWriter,
  // no knowledge of the contained type is required.
  // Implementation provided by specialization.
  virtual void AppendSetValueToWriter(MessageWriter* writer) = 0;

  // Method used by test and stub implementations of dbus::PropertySet::Set
  // to replace the property value with the set value without using a
  // dbus::MessageReader.
  virtual void ReplaceValueWithSetValue() = 0;

 protected:
  // Retrieves the associated property set.
  PropertySet* property_set() { return property_set_; }

 private:
  // Pointer to the PropertySet instance that this instance is a member of,
  // no ownership is taken and |property_set_| must outlive this class.
  PropertySet* property_set_;

  // Name of the property.
  std::string name_;

  DISALLOW_COPY_AND_ASSIGN(PropertyBase);
};

// PropertySet groups a collection of properties for a remote object
// together into a single structure, fixing their types and name such
// that calls made through it are type-safe.
//
// Clients always sub-class this to add the properties, and should always
// provide a constructor that chains up to this and then calls
// RegisterProperty() for each property defined.
//
// After creation, client code should call ConnectSignals() and most likely
// GetAll() to seed initial values and update as changes occur.
class CHROME_DBUS_EXPORT PropertySet {
 public:
  // Callback for changes to cached values of properties, either notified
  // via signal, or as a result of calls to Get() and GetAll(). The |name|
  // argument specifies the name of the property changed.
  typedef base::Callback<void(const std::string& name)> PropertyChangedCallback;

  // Constructs a property set, where |object_proxy| specifies the proxy for
  // the/ remote object that these properties are for, care should be taken to
  // ensure that this object does not outlive the lifetime of the proxy;
  // |interface| specifies the D-Bus interface of these properties, and
  // |property_changed_callback| specifies the callback for when properties
  // are changed, this may be a NULL callback.
  PropertySet(ObjectProxy* object_proxy, const std::string& interface,
              const PropertyChangedCallback& property_changed_callback);

  // Destructor; we don't hold on to any references or memory that needs
  // explicit clean-up, but clang thinks we might.
  virtual ~PropertySet();

  // Registers a property, generally called from the subclass constructor;
  // pass the |name| of the property as used in method calls and signals,
  // and the pointer to the |property| member of the structure. This will
  // call the PropertyBase::Init method.
  void RegisterProperty(const std::string& name, PropertyBase* property);

  // Connects property change notification signals to the object, generally
  // called immediately after the object is created and before calls to other
  // methods. Sub-classes may override to use different D-Bus signals.
  virtual void ConnectSignals();

  // Methods connected by ConnectSignals() and called by dbus:: when
  // a property is changed. Sub-classes may override if the property
  // changed signal provides different arguments.
  virtual void ChangedReceived(Signal* signal);
  virtual void ChangedConnected(const std::string& interface_name,
                                const std::string& signal_name,
                                bool success);

  // Callback for Get() method, |success| indicates whether or not the
  // value could be retrived, if true the new value can be obtained by
  // calling value() on the property.
  typedef base::Callback<void(bool success)> GetCallback;

  // Requests an updated value from the remote object for |property|
  // incurring a round-trip. |callback| will be called when the new
  // value is available. This may not be implemented by some interfaces,
  // and may be overriden by sub-classes if interfaces use different
  // method calls.
  virtual void Get(PropertyBase* property, GetCallback callback);
  virtual void OnGet(PropertyBase* property, GetCallback callback,
                     Response* response);

  // Queries the remote object for values of all properties and updates
  // initial values. Sub-classes may override to use a different D-Bus
  // method, or if the remote object does not support retrieving all
  // properties, either ignore or obtain each property value individually.
  virtual void GetAll();
  virtual void OnGetAll(Response* response);

  // Callback for Set() method, |success| indicates whether or not the
  // new property value was accepted by the remote object.
  typedef base::Callback<void(bool success)> SetCallback;

  // Requests that the remote object for |property| change the property to
  // its new value. |callback| will be called to indicate the success or
  // failure of the request, however the new value may not be available
  // depending on the remote object. This method may be overridden by
  // sub-classes if interfaces use different method calls.
  virtual void Set(PropertyBase* property, SetCallback callback);
  virtual void OnSet(PropertyBase* property, SetCallback callback,
                     Response* response);

  // Update properties by reading an array of dictionary entries, each
  // containing a string with the name and a variant with the value, from
  // |message_reader|. Returns false if message is in incorrect format.
  bool UpdatePropertiesFromReader(MessageReader* reader);

  // Updates a single property by reading a string with the name and a
  // variant with the value from |message_reader|. Returns false if message
  // is in incorrect format, or property type doesn't match.
  bool UpdatePropertyFromReader(MessageReader* reader);

  // Calls the property changed callback passed to the constructor, used
  // by sub-classes that do not call UpdatePropertiesFromReader() or
  // UpdatePropertyFromReader(). Takes the |name| of the changed property.
  void NotifyPropertyChanged(const std::string& name);

  // Retrieves the object proxy this property set was initialized with,
  // provided for sub-classes overriding methods that make D-Bus calls
  // and for Property<>. Not permitted with const references to this class.
  ObjectProxy* object_proxy() { return object_proxy_; }

  // Retrieves the interface of this property set.
  const std::string& interface() const { return interface_; }

 protected:
  // Get a weak pointer to this property set, provided so that sub-classes
  // overriding methods that make D-Bus calls may use the existing (or
  // override) callbacks without providing their own weak pointer factory.
  base::WeakPtr<PropertySet> GetWeakPtr() {
    return weak_ptr_factory_.GetWeakPtr();
  }

 private:
  // Pointer to object proxy for making method calls, no ownership is taken
  // so this must outlive this class.
  ObjectProxy* object_proxy_;

  // Interface of property, e.g. "org.chromium.ExampleService", this is
  // distinct from the interface of the method call itself which is the
  // general D-Bus Properties interface "org.freedesktop.DBus.Properties".
  std::string interface_;

  // Callback for property changes.
  PropertyChangedCallback property_changed_callback_;

  // Map of properties (as PropertyBase*) defined in the structure to
  // names as used in D-Bus method calls and signals. The base pointer
  // restricts property access via this map to type-unsafe and non-specific
  // actions only.
  typedef std::map<const std::string, PropertyBase*> PropertiesMap;
  PropertiesMap properties_map_;

  // Weak pointer factory as D-Bus callbacks may last longer than these
  // objects.
  base::WeakPtrFactory<PropertySet> weak_ptr_factory_;

  DISALLOW_COPY_AND_ASSIGN(PropertySet);
};

// Property template, this defines the type-specific and type-safe methods
// of properties that can be accessed as members of a PropertySet structure.
//
// Properties provide a cached value that has an initial sensible default
// until the reply to PropertySet::GetAll() is retrieved and is updated by
// all calls to that method, PropertySet::Get() and property changed signals
// also handled by PropertySet. It can be obtained by calling value() on the
// property.
//
// It is recommended that this cached value be used where necessary, with
// code using PropertySet::PropertyChangedCallback to be notified of changes,
// rather than incurring a round-trip to the remote object for each property
// access.
//
// Where a round-trip is necessary, the Get() method is provided. And to
// update the remote object value, the Set() method is also provided; these
// both simply call methods on PropertySet.
//
// Handling of particular D-Bus types is performed via specialization,
// typically the PopValueFromReader() and AppendSetValueToWriter() methods
// will need to be provided, and in rare cases a constructor to provide a
// default value. Specializations for basic D-Bus types, strings, object
// paths and arrays are provided for you.
template <class T>
class CHROME_DBUS_EXPORT Property : public PropertyBase {
 public:
  Property() {}

  // Retrieves the cached value.
  const T& value() const { return value_; }

  // Requests an updated value from the remote object incurring a
  // round-trip. |callback| will be called when the new value is available.
  // This may not be implemented by some interfaces.
  virtual void Get(dbus::PropertySet::GetCallback callback) {
    property_set()->Get(this, callback);
  }

  // Requests that the remote object change the property value to |value|,
  // |callback| will be called to indicate the success or failure of the
  // request, however the new value may not be available depending on the
  // remote object.
  virtual void Set(const T& value, dbus::PropertySet::SetCallback callback) {
    set_value_ = value;
    property_set()->Set(this, callback);
  }

  // Method used by PropertySet to retrieve the value from a MessageReader,
  // no knowledge of the contained type is required, this method returns
  // true if its expected type was found, false if not.
  bool PopValueFromReader(MessageReader* reader) override;

  // Method used by PropertySet to append the set value to a MessageWriter,
  // no knowledge of the contained type is required.
  // Implementation provided by specialization.
  void AppendSetValueToWriter(MessageWriter* writer) override;

  // Method used by test and stub implementations of dbus::PropertySet::Set
  // to replace the property value with the set value without using a
  // dbus::MessageReader.
  void ReplaceValueWithSetValue() override {
    value_ = set_value_;
    property_set()->NotifyPropertyChanged(name());
  }

  // Method used by test and stub implementations to directly set the
  // value of a property.
  void ReplaceValue(const T& value) {
    value_ = value;
    property_set()->NotifyPropertyChanged(name());
  }

  // Method used by test and stub implementations to directly set the
  // |set_value_| of a property.
  void ReplaceSetValueForTesting(const T& value) { set_value_ = value; }

 private:
  // Current cached value of the property.
  T value_;

  // Replacement value of the property.
  T set_value_;
};

template <> Property<uint8>::Property();
template <> bool Property<uint8>::PopValueFromReader(MessageReader* reader);
template <> void Property<uint8>::AppendSetValueToWriter(MessageWriter* writer);
extern template class Property<uint8>;

template <> Property<bool>::Property();
template <> bool Property<bool>::PopValueFromReader(MessageReader* reader);
template <> void Property<bool>::AppendSetValueToWriter(MessageWriter* writer);
extern template class Property<bool>;

template <> Property<int16>::Property();
template <> bool Property<int16>::PopValueFromReader(MessageReader* reader);
template <> void Property<int16>::AppendSetValueToWriter(MessageWriter* writer);
extern template class Property<int16>;

template <> Property<uint16>::Property();
template <> bool Property<uint16>::PopValueFromReader(MessageReader* reader);
template <> void Property<uint16>::AppendSetValueToWriter(
  MessageWriter* writer);
extern template class Property<uint16>;

template <> Property<int32>::Property();
template <> bool Property<int32>::PopValueFromReader(MessageReader* reader);
template <> void Property<int32>::AppendSetValueToWriter(MessageWriter* writer);
extern template class Property<int32>;

template <> Property<uint32>::Property();
template <> bool Property<uint32>::PopValueFromReader(MessageReader* reader);
template <> void Property<uint32>::AppendSetValueToWriter(
  MessageWriter* writer);
extern template class Property<uint32>;

template <> Property<int64>::Property();
template <> bool Property<int64>::PopValueFromReader(MessageReader* reader);
template <> void Property<int64>::AppendSetValueToWriter(MessageWriter* writer);
extern template class Property<int64>;

template <> Property<uint64>::Property();
template <> bool Property<uint64>::PopValueFromReader(MessageReader* reader);
template <> void Property<uint64>::AppendSetValueToWriter(
  MessageWriter* writer);
extern template class Property<uint64>;

template <> Property<double>::Property();
template <> bool Property<double>::PopValueFromReader(MessageReader* reader);
template <> void Property<double>::AppendSetValueToWriter(
  MessageWriter* writer);
extern template class Property<double>;

template <> bool Property<std::string>::PopValueFromReader(
  MessageReader* reader);
template <> void Property<std::string>::AppendSetValueToWriter(
  MessageWriter* writer);
extern template class Property<std::string>;

template <> bool Property<ObjectPath>::PopValueFromReader(
  MessageReader* reader);
template <> void Property<ObjectPath>::AppendSetValueToWriter(
  MessageWriter* writer);
extern template class Property<ObjectPath>;

template <> bool Property<std::vector<std::string> >::PopValueFromReader(
  MessageReader* reader);
template <> void Property<std::vector<std::string> >::AppendSetValueToWriter(
  MessageWriter* writer);
extern template class Property<std::vector<std::string> >;

template <> bool Property<std::vector<ObjectPath> >::PopValueFromReader(
  MessageReader* reader);
template <> void Property<std::vector<ObjectPath> >::AppendSetValueToWriter(
  MessageWriter* writer);
extern template class Property<std::vector<ObjectPath> >;

template <> bool Property<std::vector<uint8> >::PopValueFromReader(
  MessageReader* reader);
template <> void Property<std::vector<uint8> >::AppendSetValueToWriter(
  MessageWriter* writer);
extern template class Property<std::vector<uint8> >;

template <>
bool Property<std::map<std::string, std::string>>::PopValueFromReader(
    MessageReader* reader);
template <>
void Property<std::map<std::string, std::string>>::AppendSetValueToWriter(
    MessageWriter* writer);
extern template class Property<std::map<std::string, std::string>>;

template <>
bool Property<std::vector<std::pair<std::vector<uint8_t>, uint16_t>>>::
    PopValueFromReader(MessageReader* reader);
template <>
void Property<std::vector<std::pair<std::vector<uint8_t>, uint16_t>>>::
    AppendSetValueToWriter(MessageWriter* writer);
extern template class Property<
    std::vector<std::pair<std::vector<uint8_t>, uint16_t>>>;

}  // namespace dbus

#endif  // DBUS_PROPERTY_H_
