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

#include <brillo/dbus/exported_property_set.h>

#include <utility>

#include <base/bind.h>
#include <dbus/bus.h>
#include <dbus/property.h>  // For kPropertyInterface

#include <brillo/dbus/dbus_object.h>
#include <brillo/errors/error_codes.h>

namespace brillo {

namespace dbus_utils {

ExportedPropertySet::ExportedPropertySet(dbus::Bus* bus)
    : bus_(bus), weak_ptr_factory_(this) {}

void ExportedPropertySet::OnPropertiesInterfaceExported(
    DBusInterface* prop_interface) {
  signal_properties_changed_ =
      prop_interface->RegisterSignalOfType<SignalPropertiesChanged>(
          dbus::kPropertiesChanged);
}

ExportedPropertySet::PropertyWriter ExportedPropertySet::GetPropertyWriter(
    const std::string& interface_name) {
  return base::Bind(&ExportedPropertySet::WritePropertiesToDict,
                    weak_ptr_factory_.GetWeakPtr(), interface_name);
}

void ExportedPropertySet::RegisterProperty(
    const std::string& interface_name,
    const std::string& property_name,
    ExportedPropertyBase* exported_property) {
  bus_->AssertOnOriginThread();
  auto& prop_map = properties_[interface_name];
  auto res = prop_map.insert(std::make_pair(property_name, exported_property));
  CHECK(res.second) << "Property '" << property_name << "' already exists";
  // Technically, the property set exists longer than the properties themselves,
  // so we could use Unretained here rather than a weak pointer.
  ExportedPropertyBase::OnUpdateCallback cb =
      base::Bind(&ExportedPropertySet::HandlePropertyUpdated,
                 weak_ptr_factory_.GetWeakPtr(), interface_name, property_name);
  exported_property->SetUpdateCallback(cb);
}

void ExportedPropertySet::UnregisterProperty(const std::string& interface_name,
                                             const std::string& property_name) {
  bus_->AssertOnOriginThread();
  auto& prop_map = properties_[interface_name];
  auto prop_iter = prop_map.find(property_name);
  CHECK(prop_iter != prop_map.end())
      << "Property '" << property_name << "' doesn't exist";
  prop_iter->second->ClearUpdateCallback();
  prop_map.erase(prop_iter);
}

VariantDictionary ExportedPropertySet::HandleGetAll(
    const std::string& interface_name) {
  bus_->AssertOnOriginThread();
  return GetInterfaceProperties(interface_name);
}

VariantDictionary ExportedPropertySet::GetInterfaceProperties(
    const std::string& interface_name) const {
  VariantDictionary properties;
  auto property_map_itr = properties_.find(interface_name);
  if (property_map_itr != properties_.end()) {
    for (const auto& kv : property_map_itr->second)
      properties.insert(std::make_pair(kv.first, kv.second->GetValue()));
  }
  return properties;
}

void ExportedPropertySet::WritePropertiesToDict(
    const std::string& interface_name, VariantDictionary* dict) {
  *dict = GetInterfaceProperties(interface_name);
}

bool ExportedPropertySet::HandleGet(brillo::ErrorPtr* error,
                                    const std::string& interface_name,
                                    const std::string& property_name,
                                    brillo::Any* result) {
  bus_->AssertOnOriginThread();
  auto property_map_itr = properties_.find(interface_name);
  if (property_map_itr == properties_.end()) {
    brillo::Error::AddTo(error, FROM_HERE, errors::dbus::kDomain,
                         DBUS_ERROR_UNKNOWN_INTERFACE,
                         "No such interface on object.");
    return false;
  }
  LOG(INFO) << "Looking for " << property_name << " on " << interface_name;
  auto property_itr = property_map_itr->second.find(property_name);
  if (property_itr == property_map_itr->second.end()) {
    brillo::Error::AddTo(error, FROM_HERE, errors::dbus::kDomain,
                         DBUS_ERROR_UNKNOWN_PROPERTY,
                         "No such property on interface.");
    return false;
  }
  *result = property_itr->second->GetValue();
  return true;
}

bool ExportedPropertySet::HandleSet(brillo::ErrorPtr* error,
                                    const std::string& interface_name,
                                    const std::string& property_name,
                                    const brillo::Any& value) {
  bus_->AssertOnOriginThread();
  auto property_map_itr = properties_.find(interface_name);
  if (property_map_itr == properties_.end()) {
    brillo::Error::AddTo(error, FROM_HERE, errors::dbus::kDomain,
                         DBUS_ERROR_UNKNOWN_INTERFACE,
                         "No such interface on object.");
    return false;
  }
  LOG(INFO) << "Looking for " << property_name << " on " << interface_name;
  auto property_itr = property_map_itr->second.find(property_name);
  if (property_itr == property_map_itr->second.end()) {
    brillo::Error::AddTo(error, FROM_HERE, errors::dbus::kDomain,
                         DBUS_ERROR_UNKNOWN_PROPERTY,
                         "No such property on interface.");
    return false;
  }

  return property_itr->second->SetValue(error, value);
}

void ExportedPropertySet::HandlePropertyUpdated(
    const std::string& interface_name,
    const std::string& property_name,
    const ExportedPropertyBase* exported_property) {
  bus_->AssertOnOriginThread();
  // Send signal only if the object has been exported successfully.
  // This could happen when a property value is changed (which triggers
  // the notification) before D-Bus interface is completely exported/claimed.
  auto signal = signal_properties_changed_.lock();
  if (!signal)
    return;
  VariantDictionary changed_properties{
      {property_name, exported_property->GetValue()}};
  // The interface specification tells us to include this list of properties
  // which have changed, but for whom no value is conveyed.  Currently, we
  // don't do anything interesting here.
  std::vector<std::string> invalidated_properties;  // empty.
  signal->Send(interface_name, changed_properties, invalidated_properties);
}

void ExportedPropertyBase::NotifyPropertyChanged() {
  // These is a brief period after the construction of an ExportedProperty
  // when this callback is not initialized because the property has not
  // been registered with the parent ExportedPropertySet.  During this period
  // users should be initializing values via SetValue, and no notifications
  // should be triggered by the ExportedPropertySet.
  if (!on_update_callback_.is_null()) {
    on_update_callback_.Run(this);
  }
}

void ExportedPropertyBase::SetUpdateCallback(const OnUpdateCallback& cb) {
  on_update_callback_ = cb;
}

void ExportedPropertyBase::ClearUpdateCallback() {
  on_update_callback_.Reset();
}

void ExportedPropertyBase::SetAccessMode(
    ExportedPropertyBase::Access access_mode) {
  access_mode_ = access_mode;
}

ExportedPropertyBase::Access ExportedPropertyBase::GetAccessMode() const {
  return access_mode_;
}

}  // namespace dbus_utils

}  // namespace brillo
