// Copyright 2017 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.

#ifndef CHAPS_DBUS_DBUS_PROXY_WRAPPER_H_
#define CHAPS_DBUS_DBUS_PROXY_WRAPPER_H_

#include <memory>
#include <string>
#include <utility>

#include <base/bind.h>
#include <base/callback.h>
#include <base/macros.h>
#include <base/memory/ref_counted.h>
#include <base/memory/scoped_refptr.h>
#include <base/single_thread_task_runner.h>
#include <base/synchronization/waitable_event.h>
#include <brillo/dbus/dbus_method_invoker.h>
#include <dbus/object_proxy.h>

#include "chaps/dbus/scoped_bus.h"
#include "chaps/dbus_bindings/constants.h"

namespace chaps {

// libchrome's D-Bus bindings have a lot of threading restrictions which
// force us to create the D-Bus objects and call them from the same
// sequence every time. Because of this, we attempt to serialize all D-Bus
// calls and constructions to one task runner. However, our API is limited
// by the PKCS#11 interface, so we can't expose this asynchrony at a higher
// level.
//
// This stuff below is tooling to try and hide this thread-jumping as much
// as possible.

using OnObjectProxyConstructedCallback = base::Callback<void(
    bool, chaps::ScopedBus, scoped_refptr<dbus::ObjectProxy>)>;

// Wrapper around the dbus::ObjectProxy which sets up a default
// method timeout and runs D-Bus calls on the given |task_runner|.
class DBusProxyWrapper : public base::RefCountedThreadSafe<DBusProxyWrapper> {
 public:
  // 5 minutes, since some TPM operations can take a while.
  static constexpr int kDBusTimeoutMs = 5 * 60 * 1000;

  DBusProxyWrapper(scoped_refptr<base::SingleThreadTaskRunner> task_runner,
                   ScopedBus bus,
                   scoped_refptr<dbus::ObjectProxy> dbus_proxy)
      : task_runner_(task_runner),
        bus_(std::move(bus)),
        dbus_proxy_(dbus_proxy) {}

  template <typename... Args>
  std::unique_ptr<dbus::Response> CallMethod(const std::string& method_name,
                                             const Args&... args) {
    DCHECK(!task_runner_->BelongsToCurrentThread());

    std::unique_ptr<dbus::Response> resp;
    base::WaitableEvent completion_event(
        base::WaitableEvent::ResetPolicy::AUTOMATIC,
        base::WaitableEvent::InitialState::NOT_SIGNALED);
    task_runner_->PostTask(
        FROM_HERE,
        base::Bind(&DBusProxyWrapper::CallMethodOnTaskRunner<Args...>, this,
                   &resp, &completion_event, method_name, args...));
    completion_event.Wait();
    return resp;
  }

 private:
  // Hide the destructor so we can't delete this while a task might have a
  // reference to it.
  friend class base::RefCountedThreadSafe<DBusProxyWrapper>;
  virtual ~DBusProxyWrapper() {}

  template <typename... Args>
  void CallMethodOnTaskRunner(std::unique_ptr<dbus::Response>* out_resp,
                              base::WaitableEvent* completion_event,
                              const std::string& method_name,
                              const Args&... args) {
    DCHECK(task_runner_->BelongsToCurrentThread());

    *out_resp = brillo::dbus_utils::CallMethodAndBlockWithTimeout(
        kDBusTimeoutMs, dbus_proxy_.get(), kChapsInterface, method_name,
        nullptr, args...);
    completion_event->Signal();
  }

  scoped_refptr<base::SingleThreadTaskRunner> task_runner_;

  ScopedBus bus_;
  scoped_refptr<dbus::ObjectProxy> dbus_proxy_;

  DISALLOW_COPY_AND_ASSIGN(DBusProxyWrapper);
};

// To ensure we don't block forever waiting for the chapsd service to
// show up.
class ProxyWrapperConstructionTask
    : public base::RefCountedThreadSafe<ProxyWrapperConstructionTask> {
 public:
  ProxyWrapperConstructionTask();

  scoped_refptr<DBusProxyWrapper> ConstructProxyWrapper(
      scoped_refptr<base::SingleThreadTaskRunner> task_runner);

  void set_construction_callback_for_testing(
      base::Callback<void(const OnObjectProxyConstructedCallback&)> callback) {
    construction_callback_ = callback;
  }

 private:
  // Hide the destructor so we can't delete this while a task might have a
  // reference to it.
  friend class base::RefCountedThreadSafe<ProxyWrapperConstructionTask>;
  virtual ~ProxyWrapperConstructionTask() {}

  void SetObjectProxyCallback(bool success,
                              ScopedBus bus,
                              scoped_refptr<dbus::ObjectProxy> object_proxy);

  // Posted to a task runner to get an ObjectProxy.
  base::Callback<void(const OnObjectProxyConstructedCallback&)>
      construction_callback_;
  // Signaled when construction via |construction_callback_| is done.
  base::WaitableEvent completion_event_;

  // Bus and object proxy passed back from |construction_callback_|.
  bool success_;
  ScopedBus bus_;
  scoped_refptr<dbus::ObjectProxy> object_proxy_;

  DISALLOW_COPY_AND_ASSIGN(ProxyWrapperConstructionTask);
};

}  // namespace chaps

#endif  // CHAPS_DBUS_DBUS_PROXY_WRAPPER_H_
