// Copyright 2019 The Chromium 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 "chromeos/dbus/vm_plugin_dispatcher_client.h"

#include <string>
#include <utility>

#include "base/bind.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/observer_list.h"
#include "base/threading/thread_task_runner_handle.h"
#include "dbus/bus.h"
#include "dbus/message.h"
#include "third_party/cros_system_api/dbus/service_constants.h"
#include "third_party/cros_system_api/dbus/vm_plugin_dispatcher/dbus-constants.h"

namespace dispatcher = vm_tools::plugin_dispatcher;

namespace chromeos {

class VmPluginDispatcherClientImpl : public VmPluginDispatcherClient {
 public:
  VmPluginDispatcherClientImpl() {}

  ~VmPluginDispatcherClientImpl() override = default;

  void AddObserver(Observer* observer) override {
    observer_list_.AddObserver(observer);
  }

  void RemoveObserver(Observer* observer) override {
    observer_list_.RemoveObserver(observer);
  }

  void StartVm(
      const dispatcher::StartVmRequest& request,
      DBusMethodCallback<dispatcher::StartVmResponse> callback) override {
    CallMethod(dispatcher::kStartVmMethod, request, std::move(callback));
  }

  void ListVms(
      const dispatcher::ListVmRequest& request,
      DBusMethodCallback<dispatcher::ListVmResponse> callback) override {
    CallMethod(dispatcher::kListVmsMethod, request, std::move(callback));
  }

  void StopVm(
      const dispatcher::StopVmRequest& request,
      DBusMethodCallback<dispatcher::StopVmResponse> callback) override {
    CallMethod(dispatcher::kStopVmMethod, request, std::move(callback));
  }

  void SuspendVm(
      const dispatcher::SuspendVmRequest& request,
      DBusMethodCallback<dispatcher::SuspendVmResponse> callback) override {
    CallMethod(dispatcher::kSuspendVmMethod, request, std::move(callback));
  }

  void ShowVm(
      const dispatcher::ShowVmRequest& request,
      DBusMethodCallback<dispatcher::ShowVmResponse> callback) override {
    CallMethod(dispatcher::kShowVmMethod, request, std::move(callback));
  }

  void WaitForServiceToBeAvailable(
      dbus::ObjectProxy::WaitForServiceToBeAvailableCallback callback)
      override {
    vm_plugin_dispatcher_proxy_->WaitForServiceToBeAvailable(
        std::move(callback));
  }

 protected:
  void Init(dbus::Bus* bus) override {
    vm_plugin_dispatcher_proxy_ = bus->GetObjectProxy(
        dispatcher::kVmPluginDispatcherServiceName,
        dbus::ObjectPath(dispatcher::kVmPluginDispatcherServicePath));
    if (!vm_plugin_dispatcher_proxy_) {
      LOG(ERROR) << "Unable to get dbus proxy for "
                 << dispatcher::kVmPluginDispatcherServiceName;
    }

    vm_plugin_dispatcher_proxy_->ConnectToSignal(
        dispatcher::kVmPluginDispatcherInterface,
        dispatcher::kVmToolsStateChangedSignal,
        base::BindRepeating(
            &VmPluginDispatcherClientImpl::OnVmToolsStateChangedSignal,
            weak_ptr_factory_.GetWeakPtr()),
        base::BindOnce(&VmPluginDispatcherClientImpl::OnSignalConnected,
                       weak_ptr_factory_.GetWeakPtr()));

    vm_plugin_dispatcher_proxy_->ConnectToSignal(
        dispatcher::kVmPluginDispatcherInterface,
        dispatcher::kVmStateChangedSignal,
        base::BindRepeating(
            &VmPluginDispatcherClientImpl::OnVmStateChangedSignal,
            weak_ptr_factory_.GetWeakPtr()),
        base::BindOnce(&VmPluginDispatcherClientImpl::OnSignalConnected,
                       weak_ptr_factory_.GetWeakPtr()));
  }

 private:
  template <typename RequestProto, typename ResponseProto>
  void CallMethod(const std::string& method_name,
                  const RequestProto& request,
                  DBusMethodCallback<ResponseProto> callback) {
    dbus::MethodCall method_call(dispatcher::kVmPluginDispatcherInterface,
                                 method_name);
    dbus::MessageWriter writer(&method_call);

    if (!writer.AppendProtoAsArrayOfBytes(request)) {
      LOG(ERROR) << "Failed to encode protobuf for " << method_name;
      base::ThreadTaskRunnerHandle::Get()->PostTask(
          FROM_HERE, base::BindOnce(std::move(callback), base::nullopt));
      return;
    }

    vm_plugin_dispatcher_proxy_->CallMethod(
        &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
        base::BindOnce(
            &VmPluginDispatcherClientImpl::OnDBusProtoResponse<ResponseProto>,
            weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
  }

  template <typename ResponseProto>
  void OnDBusProtoResponse(DBusMethodCallback<ResponseProto> callback,
                           dbus::Response* dbus_response) {
    if (!dbus_response) {
      std::move(callback).Run(base::nullopt);
      return;
    }
    ResponseProto reponse_proto;
    dbus::MessageReader reader(dbus_response);
    if (!reader.PopArrayOfBytesAsProto(&reponse_proto)) {
      LOG(ERROR) << "Failed to parse proto from DBus Response.";
      std::move(callback).Run(base::nullopt);
      return;
    }
    std::move(callback).Run(std::move(reponse_proto));
  }

  void OnVmToolsStateChangedSignal(dbus::Signal* signal) {
    DCHECK_EQ(signal->GetInterface(), dispatcher::kVmPluginDispatcherInterface);
    DCHECK_EQ(signal->GetMember(), dispatcher::kVmToolsStateChangedSignal);

    dispatcher::VmToolsStateChangedSignal vm_state_changed_signal;
    dbus::MessageReader reader(signal);
    if (!reader.PopArrayOfBytesAsProto(&vm_state_changed_signal)) {
      LOG(ERROR) << "Failed to parse proto from DBus Signal";
      return;
    }

    for (auto& observer : observer_list_) {
      observer.OnVmToolsStateChanged(vm_state_changed_signal);
    }
  }

  void OnVmStateChangedSignal(dbus::Signal* signal) {
    DCHECK_EQ(signal->GetInterface(), dispatcher::kVmPluginDispatcherInterface);
    DCHECK_EQ(signal->GetMember(), dispatcher::kVmStateChangedSignal);

    dispatcher::VmStateChangedSignal vm_state_changed_signal;
    dbus::MessageReader reader(signal);
    if (!reader.PopArrayOfBytesAsProto(&vm_state_changed_signal)) {
      LOG(ERROR) << "Failed to parse proto from DBus Signal";
      return;
    }

    for (auto& observer : observer_list_) {
      observer.OnVmStateChanged(vm_state_changed_signal);
    }
  }

  void OnSignalConnected(const std::string& interface_name,
                         const std::string& signal_name,
                         bool is_connected) {
    DCHECK_EQ(interface_name, dispatcher::kVmPluginDispatcherInterface);
    if (!is_connected)
      LOG(ERROR) << "Failed to connect to signal: " << signal_name;
  }

  dbus::ObjectProxy* vm_plugin_dispatcher_proxy_ = nullptr;

  base::ObserverList<Observer> observer_list_;

  base::WeakPtrFactory<VmPluginDispatcherClientImpl> weak_ptr_factory_{this};

  DISALLOW_COPY_AND_ASSIGN(VmPluginDispatcherClientImpl);
};

VmPluginDispatcherClient::VmPluginDispatcherClient() = default;

VmPluginDispatcherClient::~VmPluginDispatcherClient() = default;

std::unique_ptr<VmPluginDispatcherClient> VmPluginDispatcherClient::Create() {
  return std::make_unique<VmPluginDispatcherClientImpl>();
}

}  // namespace chromeos
