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

#include <map>
#include <string>

#include <base/bind.h>
#include <base/bind_helpers.h>
#include <base/json/json_writer.h>
#include <dbus/bus.h>
#include <dbus/object_path.h>
#include <dbus/values_util.h>

#include "buffet/async_event_sequencer.h"
#include "buffet/dbus_constants.h"
#include "buffet/dbus_utils.h"
#include "buffet/error.h"

using buffet::dbus_utils::GetBadArgsError;
using buffet::dbus_utils::GetDBusError;

namespace buffet {

Manager::Manager(dbus::Bus* bus)
    : bus_(bus),
      exported_object_(bus->GetExportedObject(
          dbus::ObjectPath(dbus_constants::kManagerServicePath))) { }

Manager::~Manager() {
  // Prevent the properties object from making calls to the exported object.
  properties_.reset(nullptr);
  // Unregister ourselves from the Bus.  This prevents the bus from calling
  // our callbacks in between the Manager's death and the bus unregistering
  // our exported object on shutdown.  Unretained makes no promises of memory
  // management.
  exported_object_->Unregister();
  exported_object_ = nullptr;
}

void Manager::Init(const OnInitFinish& cb) {
  scoped_refptr<dbus_utils::AsyncEventSequencer> sequencer(
      new dbus_utils::AsyncEventSequencer());
  exported_object_->ExportMethod(
      dbus_constants::kManagerInterface,
      dbus_constants::kManagerCheckDeviceRegistered,
      dbus_utils::GetExportableDBusMethod(
          base::Bind(&Manager::HandleCheckDeviceRegistered,
          base::Unretained(this))),
      sequencer->GetExportHandler(
          dbus_constants::kManagerInterface,
          dbus_constants::kManagerCheckDeviceRegistered,
          "Failed exporting CheckDeviceRegistered method",
          true));
  exported_object_->ExportMethod(
      dbus_constants::kManagerInterface,
      dbus_constants::kManagerGetDeviceInfo,
      dbus_utils::GetExportableDBusMethod(
          base::Bind(&Manager::HandleGetDeviceInfo,
          base::Unretained(this))),
      sequencer->GetExportHandler(
          dbus_constants::kManagerInterface,
          dbus_constants::kManagerGetDeviceInfo,
          "Failed exporting GetDeviceInfo method",
          true));
  exported_object_->ExportMethod(
      dbus_constants::kManagerInterface,
      dbus_constants::kManagerStartRegisterDevice,
      dbus_utils::GetExportableDBusMethod(
          base::Bind(&Manager::HandleStartRegisterDevice,
          base::Unretained(this))),
      sequencer->GetExportHandler(
          dbus_constants::kManagerInterface,
          dbus_constants::kManagerStartRegisterDevice,
          "Failed exporting StartRegisterDevice method",
          true));
  exported_object_->ExportMethod(
      dbus_constants::kManagerInterface,
      dbus_constants::kManagerFinishRegisterDevice,
      dbus_utils::GetExportableDBusMethod(
          base::Bind(&Manager::HandleFinishRegisterDevice,
          base::Unretained(this))),
      sequencer->GetExportHandler(
          dbus_constants::kManagerInterface,
          dbus_constants::kManagerFinishRegisterDevice,
          "Failed exporting FinishRegisterDevice method",
          true));
  exported_object_->ExportMethod(
      dbus_constants::kManagerInterface,
      dbus_constants::kManagerUpdateStateMethod,
      dbus_utils::GetExportableDBusMethod(
          base::Bind(&Manager::HandleUpdateState,
          base::Unretained(this))),
      sequencer->GetExportHandler(
          dbus_constants::kManagerInterface,
          dbus_constants::kManagerUpdateStateMethod,
          "Failed exporting UpdateState method",
          true));
  exported_object_->ExportMethod(
      dbus_constants::kManagerInterface, dbus_constants::kManagerTestMethod,
      dbus_utils::GetExportableDBusMethod(
          base::Bind(&Manager::HandleTestMethod, base::Unretained(this))),
      sequencer->GetExportHandler(
          dbus_constants::kManagerInterface, dbus_constants::kManagerTestMethod,
          "Failed exporting TestMethod method",
          true));
  properties_.reset(new Properties(bus_));
  // TODO(wiley): Initialize all properties appropriately before claiming
  //              the properties interface.
  properties_->state_.SetValue("{}");
  properties_->Init(
      sequencer->GetHandler("Manager properties export failed.", true));
  sequencer->OnAllTasksCompletedCall({cb});
  device_info_.Load();
}

scoped_ptr<dbus::Response> Manager::HandleCheckDeviceRegistered(
    dbus::MethodCall* method_call) {
  // Read the parameters to the method.
  dbus::MessageReader reader(method_call);
  if (reader.HasMoreData()) {
    return GetBadArgsError(method_call,
                           "Too many parameters to CheckDeviceRegistered");
  }

  LOG(INFO) << "Received call to Manager.CheckDeviceRegistered()";

  chromeos::ErrorPtr error;
  bool registered = device_info_.CheckRegistration(&error);
  // If it fails due to any reason other than 'device not registered',
  // treat it as a real error and report it to the caller.
  if (!registered &&
      !error->HasError(kErrorDomainGCD, "device_not_registered")) {
    return GetDBusError(method_call, error.get());
  }

  std::string device_id;
  if (registered) {
    device_id = device_info_.GetDeviceId(&error);
    if (device_id.empty())
      return GetDBusError(method_call, error.get());
  }
  // Send back our response.
  scoped_ptr<dbus::Response> response(
      dbus::Response::FromMethodCall(method_call));
  dbus::MessageWriter writer(response.get());
  writer.AppendString(device_id);
  return response.Pass();
}

scoped_ptr<dbus::Response> Manager::HandleGetDeviceInfo(
    dbus::MethodCall* method_call) {
  // Read the parameters to the method.
  dbus::MessageReader reader(method_call);
  if (reader.HasMoreData()) {
    return GetBadArgsError(method_call,
                           "Too many parameters to GetDeviceInfo");
  }

  LOG(INFO) << "Received call to Manager.GetDeviceInfo()";

  std::string device_info_str;
  chromeos::ErrorPtr error;
  auto device_info = device_info_.GetDeviceInfo(&error);
  if (!device_info)
    return GetDBusError(method_call, error.get());

  base::JSONWriter::Write(device_info.get(), &device_info_str);

  // Send back our response.
  scoped_ptr<dbus::Response> response(
      dbus::Response::FromMethodCall(method_call));
  dbus::MessageWriter writer(response.get());
  writer.AppendString(device_info_str);
  return response.Pass();
}

scoped_ptr<dbus::Response> Manager::HandleStartRegisterDevice(
    dbus::MethodCall* method_call) {
  // Read the parameters to the method.
  dbus::MessageReader reader(method_call);
  if (!reader.HasMoreData()) {
    return GetBadArgsError(method_call, "No parameters to StartRegisterDevice");
  }

  dbus::MessageReader array_reader(nullptr);
  if (!reader.PopArray(&array_reader))
    return GetBadArgsError(method_call, "Failed to read the parameter array");
  std::map<std::string, std::shared_ptr<base::Value>> params;
  while (array_reader.HasMoreData()) {
    dbus::MessageReader dict_entry_reader(nullptr);
    if (!array_reader.PopDictEntry(&dict_entry_reader))
      return GetBadArgsError(method_call, "Failed to get a call parameter");
    std::string key;
    if (!dict_entry_reader.PopString(&key))
      return GetBadArgsError(method_call, "Failed to read parameter key");
    base::Value* value = dbus::PopDataAsValue(&dict_entry_reader);
    if (!value)
      return GetBadArgsError(method_call, "Failed to read parameter value");
    params.insert(std::make_pair(key, std::shared_ptr<base::Value>(value)));
  }
  if (reader.HasMoreData())
    return GetBadArgsError(method_call,
                           "Too many parameters to StartRegisterDevice");

  LOG(INFO) << "Received call to Manager.StartRegisterDevice()";

  chromeos::ErrorPtr error;
  std::string id = device_info_.StartRegistration(params, &error);
  if (id.empty())
    return GetDBusError(method_call, error.get());

  // Send back our response.
  scoped_ptr<dbus::Response> response(
      dbus::Response::FromMethodCall(method_call));
  dbus::MessageWriter writer(response.get());
  writer.AppendString(id);
  return response.Pass();
}

scoped_ptr<dbus::Response> Manager::HandleFinishRegisterDevice(
  dbus::MethodCall* method_call) {
  // Read the parameters to the method.
  dbus::MessageReader reader(method_call);
  if (!reader.HasMoreData()) {
    return GetBadArgsError(method_call,
                           "No parameters to FinishRegisterDevice");
  }
  std::string user_auth_code;
  if (!reader.PopString(&user_auth_code)) {
    return GetBadArgsError(method_call, "Failed to read UserAuthCode");
  }
  if (reader.HasMoreData()) {
    return GetBadArgsError(method_call,
                           "Too many parameters to FinishRegisterDevice");
  }

  LOG(INFO) << "Received call to Manager.FinishRegisterDevice()";
  chromeos::ErrorPtr error;
  if (!device_info_.FinishRegistration(user_auth_code, &error))
    return GetDBusError(method_call, error.get());

  std::string device_id = device_info_.GetDeviceId(&error);
  if (device_id.empty())
    return GetDBusError(method_call, error.get());

  // Send back our response.
  scoped_ptr<dbus::Response> response(
    dbus::Response::FromMethodCall(method_call));
  dbus::MessageWriter writer(response.get());
  writer.AppendString(device_id);
  return response.Pass();
}

scoped_ptr<dbus::Response> Manager::HandleUpdateState(
    dbus::MethodCall *method_call) {
  // Read the parameters to the method.
  dbus::MessageReader reader(method_call);
  if (!reader.HasMoreData()) {
    return GetBadArgsError(method_call, "No parameters to UpdateState");
  }
  std::string json_state_fragment;
  if (!reader.PopString(&json_state_fragment)) {
    return GetBadArgsError(method_call, "Failed to read json_state_fragment");
  }
  if (reader.HasMoreData()) {
    return GetBadArgsError(method_call, "Too many parameters to UpdateState");
  }

  LOG(INFO) << "Received call to Manager.UpdateState()";
  // TODO(wiley): Merge json state blobs intelligently.
  properties_->state_.SetValue(json_state_fragment);

  // Send back our response.
  return dbus::Response::FromMethodCall(method_call);
}

scoped_ptr<dbus::Response> Manager::HandleTestMethod(
    dbus::MethodCall* method_call) {
  LOG(INFO) << "Received call to test method.";
  return scoped_ptr<dbus::Response>();
}

}  // namespace buffet
