// Copyright 2018 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 "bluetooth/newblued/agent_manager_interface_handler.h"

#include <string>

#include <base/bind.h>
#include <base/stl_util.h>
#include <base/strings/stringprintf.h>
#include <chromeos/dbus/service_constants.h>
#include <dbus/message.h>
#include <dbus/object_proxy.h>

#include "bluetooth/common/util.h"

namespace bluetooth {

AgentManagerInterfaceHandler::AgentManagerInterfaceHandler(
    scoped_refptr<dbus::Bus> bus,
    ExportedObjectManagerWrapper* exported_object_manager_wrapper)
    : bus_(bus),
      exported_object_manager_wrapper_(exported_object_manager_wrapper),
      weak_ptr_factory_(this) {}

void AgentManagerInterfaceHandler::Init() {
  dbus::ObjectPath agent_manager_object_path(
      bluetooth_agent_manager::kBluetoothAgentManagerServicePath);
  exported_object_manager_wrapper_->AddExportedInterface(
      agent_manager_object_path,
      bluetooth_agent_manager::kBluetoothAgentManagerInterface);
  ExportedInterface* agent_manager_interface =
      exported_object_manager_wrapper_->GetExportedInterface(
          agent_manager_object_path,
          bluetooth_agent_manager::kBluetoothAgentManagerInterface);

  agent_manager_interface->AddSimpleMethodHandlerWithErrorAndMessage(
      bluetooth_agent_manager::kRegisterAgent, base::Unretained(this),
      &AgentManagerInterfaceHandler::HandleRegisterAgent);
  agent_manager_interface->AddSimpleMethodHandlerWithErrorAndMessage(
      bluetooth_agent_manager::kUnregisterAgent, base::Unretained(this),
      &AgentManagerInterfaceHandler::HandleUnregisterAgent);
  agent_manager_interface->AddSimpleMethodHandlerWithErrorAndMessage(
      bluetooth_agent_manager::kRequestDefaultAgent, base::Unretained(this),
      &AgentManagerInterfaceHandler::HandleRequestDefaultAgent);

  agent_manager_interface->ExportAndBlock();
}

void AgentManagerInterfaceHandler::DisplayPasskey(
    const std::string& device_address, uint32_t passkey) {
  LOG(INFO) << "Please enter passkey " << passkey << " on the device";

  if (default_agent_client_.empty() ||
      !base::ContainsKey(agent_object_paths_, default_agent_client_)) {
    LOG(WARNING) << "No agent available to display passkey";
    return;
  }

  dbus::MethodCall method_call(bluetooth_agent::kBluetoothAgentInterface,
                               bluetooth_agent::kDisplayPasskey);

  dbus::MessageWriter writer(&method_call);
  writer.AppendObjectPath(
      dbus::ObjectPath(ConvertDeviceAddressToObjectPath(device_address)));
  writer.AppendUint32(passkey);
  // The number of keys that have been pressed. Currently hardcode to 0 until
  // we have support for this information in libnewblue.
  writer.AppendUint16(0);

  dbus::ObjectProxy* agent_object_proxy = bus_->GetObjectProxy(
      default_agent_client_, agent_object_paths_[default_agent_client_]);
  agent_object_proxy->CallMethod(
      &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
      base::Bind(&AgentManagerInterfaceHandler::OnDisplayPasskeySent,
                 weak_ptr_factory_.GetWeakPtr()));
}

void AgentManagerInterfaceHandler::OnDisplayPasskeySent(
    dbus::Response* response) {
  VLOG(1) << __func__;
}

bool AgentManagerInterfaceHandler::HandleRegisterAgent(
    brillo::ErrorPtr* error,
    dbus::Message* message,
    dbus::ObjectPath agent_object_path,
    std::string capability) {
  VLOG(1) << "Registering agent " << agent_object_path.value()
          << " with capability = " << capability;
  agent_object_paths_[message->GetSender()] = agent_object_path;
  return true;
}

bool AgentManagerInterfaceHandler::HandleUnregisterAgent(
    brillo::ErrorPtr* error,
    dbus::Message* message,
    dbus::ObjectPath agent_object_path) {
  VLOG(1) << __func__;

  if (base::ContainsKey(agent_object_paths_, message->GetSender())) {
    if (agent_object_paths_[message->GetSender()] != agent_object_path)
      LOG(WARNING) << "Agent path does not match.";
    agent_object_paths_.erase(message->GetSender());
  }

  if (default_agent_client_ == message->GetSender())
    default_agent_client_ = "";

  return true;
}

bool AgentManagerInterfaceHandler::HandleRequestDefaultAgent(
    brillo::ErrorPtr* error,
    dbus::Message* message,
    dbus::ObjectPath agent_object_path) {
  VLOG(1) << "Setting default agent " << agent_object_path.value();

  if (!base::ContainsKey(agent_object_paths_, message->GetSender())) {
    brillo::Error::AddTo(
        error, FROM_HERE, brillo::errors::dbus::kDomain,
        bluetooth_adapter::kErrorFailed,
        base::StringPrintf("Client %s has not registered agent.",
                           message->GetSender().c_str()));
    return false;
  }

  default_agent_client_ = message->GetSender();

  if (agent_object_path != agent_object_paths_[default_agent_client_])
    LOG(WARNING) << "Agent path does not match.";

  return true;
}

}  // namespace bluetooth
