// Copyright 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.

#include "chromeos/dbus/nfc_record_client.h"

#include "base/bind.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "chromeos/dbus/nfc_device_client.h"
#include "chromeos/dbus/nfc_tag_client.h"
#include "dbus/bus.h"
#include "third_party/cros_system_api/dbus/service_constants.h"

using chromeos::nfc_client_helpers::DBusObjectMap;
using chromeos::nfc_client_helpers::ObjectProxyTree;

namespace chromeos {

NfcRecordClient::Properties::Properties(
    dbus::ObjectProxy* object_proxy,
    const PropertyChangedCallback& callback)
    : NfcPropertySet(object_proxy,
                     nfc_record::kNfcRecordInterface,
                     callback) {
  RegisterProperty(nfc_record::kTypeProperty, &type);
  RegisterProperty(nfc_record::kLanguageProperty, &language);
  RegisterProperty(nfc_record::kEncodingProperty, &encoding);
  RegisterProperty(nfc_record::kRepresentationProperty, &representation);
  RegisterProperty(nfc_record::kUriProperty, &uri);
  RegisterProperty(nfc_record::kMimeTypeProperty, &mime_type);
  RegisterProperty(nfc_record::kSizeProperty, &size);
  RegisterProperty(nfc_record::kActionProperty, &action);
}

NfcRecordClient::Properties::~Properties() {
}

// The NfcRecordClient implementation used in production.
class NfcRecordClientImpl : public NfcRecordClient,
                            public NfcDeviceClient::Observer,
                            public NfcTagClient::Observer,
                            public DBusObjectMap::Delegate {
 public:
  explicit NfcRecordClientImpl(NfcDeviceClient* device_client,
                               NfcTagClient* tag_client)
      : bus_(NULL),
        device_client_(device_client),
        tag_client_(tag_client),
        weak_ptr_factory_(this) {
    DCHECK(device_client);
    DCHECK(tag_client);
  }

  virtual ~NfcRecordClientImpl() {
    DCHECK(device_client_);
    DCHECK(tag_client_);
    device_client_->RemoveObserver(this);
    tag_client_->RemoveObserver(this);
  }

  // NfcRecordClient override.
  virtual void AddObserver(NfcRecordClient::Observer* observer) override {
    DCHECK(observer);
    observers_.AddObserver(observer);
  }

  // NfcRecordClient override.
  virtual void RemoveObserver(NfcRecordClient::Observer* observer) override {
    DCHECK(observer);
    observers_.RemoveObserver(observer);
  }

  virtual std::vector<dbus::ObjectPath> GetRecordsForDevice(
      const dbus::ObjectPath& device_path) override {
    DBusObjectMap* object_map =
        devices_and_tags_to_object_maps_.GetObjectMap(device_path);
    if (!object_map)
      return std::vector<dbus::ObjectPath>();
    return object_map->GetObjectPaths();
  }

  virtual std::vector<dbus::ObjectPath> GetRecordsForTag(
      const dbus::ObjectPath& tag_path) override {
    return GetRecordsForDevice(tag_path);
  }

  // NfcRecordClient override.
  virtual Properties* GetProperties(
      const dbus::ObjectPath& object_path) override {
    return static_cast<Properties*>(
        devices_and_tags_to_object_maps_.FindObjectProperties(object_path));
  }

 protected:
  // DBusClient override.
  virtual void Init(dbus::Bus* bus) override {
    VLOG(1) << "Creating NfcRecordClient impl";
    DCHECK(bus);
    bus_ = bus;
    DCHECK(device_client_);
    DCHECK(tag_client_);
    device_client_->AddObserver(this);
    tag_client_->AddObserver(this);
  }

 private:
  // NfcDeviceClient::Observer override.
  virtual void DeviceAdded(const dbus::ObjectPath& object_path) override {
    VLOG(1) << "Device added. Creating map for record proxies belonging to "
            << "device: " << object_path.value();
    devices_and_tags_to_object_maps_.CreateObjectMap(
        object_path, nfc_record::kNfcRecordServiceName, this, bus_);
  }

  // NfcDeviceClient::Observer override.
  virtual void DeviceRemoved(const dbus::ObjectPath& object_path) override {
    // Neard doesn't send out property changed signals for the records that
    // are removed when the device they belong to is removed. Clean up the
    // object proxies for records that belong to the removed device.
    // Note: DBusObjectMap guarantees that the Properties structure for the
    // removed adapter will be valid before this method returns.
    VLOG(1) << "Device removed. Cleaning up record proxies belonging to "
            << "device: " << object_path.value();
    devices_and_tags_to_object_maps_.RemoveObjectMap(object_path);
  }

  // NfcDeviceClient::Observer override.
  virtual void DevicePropertyChanged(
      const dbus::ObjectPath& object_path,
      const std::string& property_name) override {
    // Update the record proxies using records from the device.
    DCHECK(device_client_);
    NfcDeviceClient::Properties* device_properties =
        device_client_->GetProperties(object_path);

    // Ignore changes to properties other than "Records".
    if (property_name != device_properties->records.name())
      return;

    // Update known records.
    VLOG(1) << "NFC records changed.";
    const std::vector<dbus::ObjectPath>& received_records =
        device_properties->records.value();
    DBusObjectMap* object_map =
        devices_and_tags_to_object_maps_.GetObjectMap(object_path);
    DCHECK(object_map);
    object_map->UpdateObjects(received_records);
  }

  // NfcTagClient::Observer override.
  virtual void TagAdded(const dbus::ObjectPath& object_path) override {
    VLOG(1) << "Tag added. Creating map for record proxies belonging to "
            << "tag: " << object_path.value();
    devices_and_tags_to_object_maps_.CreateObjectMap(
        object_path, nfc_record::kNfcRecordServiceName, this, bus_);
  }

  // NfcTagClient::Observer override.
  virtual void TagRemoved(const dbus::ObjectPath& object_path) override {
    // Neard doesn't send out property changed signals for the records that
    // are removed when the tag they belong to is removed. Clean up the
    // object proxies for records that belong to the removed tag.
    // Note: DBusObjectMap guarantees that the Properties structure for the
    // removed adapter will be valid before this method returns.
    VLOG(1) << "Tag removed. Cleaning up record proxies belonging to "
            << "tag: " << object_path.value();
    devices_and_tags_to_object_maps_.RemoveObjectMap(object_path);
  }

  // NfcTagClient::Observer override.
  virtual void TagPropertyChanged(const dbus::ObjectPath& object_path,
                                  const std::string& property_name) override {
    // Update the record proxies using records from the tag.
    DCHECK(device_client_);
    NfcTagClient::Properties* tag_properties =
        tag_client_->GetProperties(object_path);

    // Ignore changes to properties other than "Records".
    if (property_name != tag_properties->records.name())
      return;

    // Update known records.
    VLOG(1) << "NFC records changed.";
    const std::vector<dbus::ObjectPath>& received_records =
        tag_properties->records.value();
    DBusObjectMap* object_map =
        devices_and_tags_to_object_maps_.GetObjectMap(object_path);
    DCHECK(object_map);
    object_map->UpdateObjects(received_records);

    // When rewriting the record to a tag, neard fires a property changed
    // signal for the tags "Records" property, without creating a new object
    // path. Sync the properties of all records here, in case Update objects
    // doesn't do it.
    VLOG(1) << "Fetch properties for all records.";
    object_map->RefreshAllProperties();
  }

  // nfc_client_helpers::DBusObjectMap::Delegate override.
  virtual NfcPropertySet* CreateProperties(
      dbus::ObjectProxy* object_proxy) override {
    Properties* properties = new Properties(
        object_proxy,
        base::Bind(&NfcRecordClientImpl::OnPropertyChanged,
                   weak_ptr_factory_.GetWeakPtr(),
                   object_proxy->object_path()));
    properties->SetAllPropertiesReceivedCallback(
        base::Bind(&NfcRecordClientImpl::OnPropertiesReceived,
                   weak_ptr_factory_.GetWeakPtr(),
                   object_proxy->object_path()));
    return properties;
  }

  // nfc_client_helpers::DBusObjectMap::Delegate override.
  virtual void ObjectAdded(const dbus::ObjectPath& object_path) override {
    FOR_EACH_OBSERVER(NfcRecordClient::Observer, observers_,
                      RecordAdded(object_path));
  }

  // nfc_client_helpers::DBusObjectMap::Delegate override.
  virtual void ObjectRemoved(const dbus::ObjectPath& object_path) override {
    FOR_EACH_OBSERVER(NfcRecordClient::Observer, observers_,
                      RecordRemoved(object_path));
  }

  // Called by NfcPropertySet when a property value is changed, either by
  // result of a signal or response to a GetAll() or Get() call.
  void OnPropertyChanged(const dbus::ObjectPath& object_path,
                         const std::string& property_name) {
    VLOG(1) << "Record property changed; Path: " << object_path.value()
            << " Property: " << property_name;
    FOR_EACH_OBSERVER(NfcRecordClient::Observer, observers_,
                      RecordPropertyChanged(object_path, property_name));
  }

  // Called by NfcPropertySet when all properties have been processed as a
  // result of a call to GetAll.
  void OnPropertiesReceived(const dbus::ObjectPath& object_path) {
    VLOG(1) << "All record properties received; Path: " << object_path.value();
    FOR_EACH_OBSERVER(NfcRecordClient::Observer, observers_,
                      RecordPropertiesReceived(object_path));
  }

  // We maintain a pointer to the bus to be able to request proxies for
  // new NFC records that appear.
  dbus::Bus* bus_;

  // List of observers interested in event notifications.
  ObserverList<NfcRecordClient::Observer> observers_;

  // Mapping from object paths to object proxies and properties structures that
  // were already created by us. Record objects belong to either Tag or Device
  // objects. This structure stores a different DBusObjectMap for each known
  // device and tag.
  ObjectProxyTree devices_and_tags_to_object_maps_;

  // The device and tag clients that we listen to events notifications from.
  NfcDeviceClient* device_client_;
  NfcTagClient* tag_client_;
  // 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<NfcRecordClientImpl> weak_ptr_factory_;

  DISALLOW_COPY_AND_ASSIGN(NfcRecordClientImpl);
};

NfcRecordClient::NfcRecordClient() {
}

NfcRecordClient::~NfcRecordClient() {
}

NfcRecordClient* NfcRecordClient::Create(NfcDeviceClient* device_client,
                                         NfcTagClient* tag_client) {
  return new NfcRecordClientImpl(device_client, tag_client);
}

}  // namespace chromeos
