// 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_object_manager.h>

#include <vector>

#include <brillo/dbus/async_event_sequencer.h>
#include <dbus/object_manager.h>

using brillo::dbus_utils::AsyncEventSequencer;

namespace brillo {

namespace dbus_utils {

ExportedObjectManager::ExportedObjectManager(scoped_refptr<dbus::Bus> bus,
                                             const dbus::ObjectPath& path)
    : bus_(bus), dbus_object_(nullptr, bus, path) {}

void ExportedObjectManager::RegisterAsync(
    const AsyncEventSequencer::CompletionAction& completion_callback) {
  VLOG(1) << "Registering object manager";
  bus_->AssertOnOriginThread();
  DBusInterface* itf =
      dbus_object_.AddOrGetInterface(dbus::kObjectManagerInterface);
  itf->AddSimpleMethodHandler(dbus::kObjectManagerGetManagedObjects,
                              base::Unretained(this),
                              &ExportedObjectManager::HandleGetManagedObjects);

  signal_itf_added_ = itf->RegisterSignalOfType<SignalInterfacesAdded>(
      dbus::kObjectManagerInterfacesAdded);
  signal_itf_removed_ = itf->RegisterSignalOfType<SignalInterfacesRemoved>(
      dbus::kObjectManagerInterfacesRemoved);
  dbus_object_.RegisterAsync(completion_callback);
}

void ExportedObjectManager::ClaimInterface(
    const dbus::ObjectPath& path,
    const std::string& interface_name,
    const ExportedPropertySet::PropertyWriter& property_writer) {
  bus_->AssertOnOriginThread();
  // We're sending signals that look like:
  //   org.freedesktop.DBus.ObjectManager.InterfacesAdded (
  //       OBJPATH object_path,
  //       DICT<STRING,DICT<STRING,VARIANT>> interfaces_and_properties);
  VariantDictionary property_dict;
  property_writer.Run(&property_dict);
  std::map<std::string, VariantDictionary> interfaces_and_properties{
      {interface_name, property_dict}};
  signal_itf_added_.lock()->Send(path, interfaces_and_properties);
  registered_objects_[path][interface_name] = property_writer;
}

void ExportedObjectManager::ReleaseInterface(
    const dbus::ObjectPath& path, const std::string& interface_name) {
  bus_->AssertOnOriginThread();
  auto interfaces_for_path_itr = registered_objects_.find(path);
  CHECK(interfaces_for_path_itr != registered_objects_.end())
      << "Attempting to signal interface removal for path " << path.value()
      << " which was never registered.";
  auto& interfaces_for_path = interfaces_for_path_itr->second;
  auto property_for_interface_itr = interfaces_for_path.find(interface_name);
  CHECK(property_for_interface_itr != interfaces_for_path.end())
      << "Attempted to remove interface " << interface_name << " from "
      << path.value() << ", but this interface was never registered.";
  interfaces_for_path.erase(interface_name);
  if (interfaces_for_path.empty())
    registered_objects_.erase(path);

  // We're sending signals that look like:
  //   org.freedesktop.DBus.ObjectManager.InterfacesRemoved (
  //       OBJPATH object_path, ARRAY<STRING> interfaces);
  signal_itf_removed_.lock()->Send(path,
                                   std::vector<std::string>{interface_name});
}

ExportedObjectManager::ObjectMap
ExportedObjectManager::HandleGetManagedObjects() {
  // Implements the GetManagedObjects method:
  //
  // org.freedesktop.DBus.ObjectManager.GetManagedObjects (
  //     out DICT<OBJPATH,
  //              DICT<STRING,
  //                   DICT<STRING,VARIANT>>> )
  bus_->AssertOnOriginThread();
  ExportedObjectManager::ObjectMap objects;
  for (const auto& path_pair : registered_objects_) {
    std::map<std::string, VariantDictionary>& interfaces =
        objects[path_pair.first];
    const InterfaceProperties& interface2properties = path_pair.second;
    for (const auto& interface : interface2properties) {
      interface.second.Run(&interfaces[interface.first]);
    }
  }
  return objects;
}

}  // namespace dbus_utils

}  // namespace brillo
