// 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 CHROME_DBUS_EXPORT PropertyBase {
 public:
  PropertyBase();
  virtual ~PropertyBase();

  // 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_; }

  // Returns true if property is valid, false otherwise.
  bool is_valid() const { return is_valid_; }

  // Allows to mark Property as valid or invalid.
  void set_valid(bool is_valid) { is_valid_ = is_valid; }

  // 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_;

  bool is_valid_;

  // 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:
  // Invalidates properties by reading an array of names, from
  // |message_reader|. Returns false if message is in incorrect format.
  bool InvalidatePropertiesFromReader(MessageReader* reader);

  // 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() {}
  ~Property() override {}

  // 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_
