// 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 "buffet/exported_object_manager.h"

#include <dbus/object_manager.h>

#include "buffet/async_event_sequencer.h"

namespace buffet {

namespace dbus_utils {

ExportedObjectManager::ExportedObjectManager(scoped_refptr<dbus::Bus> bus,
                                             const dbus::ObjectPath& path)
    : bus_(bus), exported_object_(bus->GetExportedObject(path)) {}

void ExportedObjectManager::Init(const OnInitFinish& cb) {
  bus_->AssertOnOriginThread();
  scoped_refptr<dbus_utils::AsyncEventSequencer> sequencer(
      new dbus_utils::AsyncEventSequencer());
  exported_object_->ExportMethod(
      dbus::kObjectManagerInterface,
      dbus::kObjectManagerGetManagedObjects,
      base::Bind(&ExportedObjectManager::HandleGetManagedObjects,
                 AsWeakPtr()),
      sequencer->GetExportHandler(
          dbus::kObjectManagerInterface,
          dbus::kObjectManagerGetManagedObjects,
          "Failed exporting GetManagedObjects method of ObjectManager",
          false));
  sequencer->OnAllTasksCompletedCall({cb});
}

void ExportedObjectManager::ClaimInterface(
    const dbus::ObjectPath& path,
    const std::string& interface_name,
    const 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);
  dbus::Signal signal(dbus::kObjectManagerInterface,
                      dbus::kObjectManagerInterfacesAdded);
  dbus::MessageWriter signal_writer(&signal);
  dbus::MessageWriter all_interfaces(&signal);
  dbus::MessageWriter each_interface(&signal);
  signal_writer.AppendObjectPath(path);
  signal_writer.OpenArray("{sa{sv}}", &all_interfaces);
  all_interfaces.OpenDictEntry(&each_interface);
  each_interface.AppendString(interface_name);
  property_writer.Run(&each_interface);
  all_interfaces.CloseContainer(&each_interface);
  signal_writer.CloseContainer(&all_interfaces);
  exported_object_->SendSignal(&signal);
  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.size() < 1) {
    registered_objects_.erase(path);
  }
  // We're sending signals that look like:
  //   org.freedesktop.DBus.ObjectManager.InterfacesRemoved (
  //       OBJPATH object_path, ARRAY<STRING> interfaces);
  dbus::Signal signal(dbus::kObjectManagerInterface,
                      dbus::kObjectManagerInterfacesRemoved);
  dbus::MessageWriter signal_writer(&signal);
  signal_writer.AppendObjectPath(path);
  dbus::MessageWriter interface_writer(nullptr);
  signal_writer.OpenArray("s", &interface_writer);
  interface_writer.AppendString(interface_name);
  signal_writer.CloseContainer(&interface_writer);
  exported_object_->SendSignal(&signal);
}

void ExportedObjectManager::HandleGetManagedObjects(
    dbus::MethodCall* method_call,
    dbus::ExportedObject::ResponseSender response_sender) const {
  // Implements the GetManagedObjects method:
  //
  // org.freedesktop.DBus.ObjectManager.GetManagedObjects (
  //     out DICT<OBJPATH,
  //              DICT<STRING,
  //                   DICT<STRING,VARIANT>>> )
  bus_->AssertOnOriginThread();
  scoped_ptr<dbus::Response> response(
      dbus::Response::FromMethodCall(method_call));
  dbus::MessageWriter response_writer(response.get());
  dbus::MessageWriter all_object_paths(nullptr);
  dbus::MessageWriter each_object_path(nullptr);
  dbus::MessageWriter all_interfaces(nullptr);
  dbus::MessageWriter each_interface(nullptr);

  response_writer.OpenArray("{oa{sa{sv}}}", &all_object_paths);
  for (const auto path_pair : registered_objects_) {
    const dbus::ObjectPath& path = path_pair.first;
    const InterfaceProperties& interface2properties = path_pair.second;
    all_object_paths.OpenDictEntry(&each_object_path);
    each_object_path.AppendObjectPath(path);
    each_object_path.OpenArray("{sa{sv}}", &all_interfaces);
    for (const auto interface : interface2properties) {
      const std::string& interface_name = interface.first;
      const PropertyWriter& property_writer = interface.second;
      all_interfaces.OpenDictEntry(&each_interface);
      each_interface.AppendString(interface_name);
      property_writer.Run(&each_interface);
      all_interfaces.CloseContainer(&each_interface);
    }
    each_object_path.CloseContainer(&all_interfaces);
    all_object_paths.CloseContainer(&each_object_path);
  }
  response_writer.CloseContainer(&all_object_paths);
  response_sender.Run(response.Pass());
}

}  //  namespace dbus_utils

}  //  namespace buffet
