// Copyright (c) 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.
//
// This file provides helper classes to allow all new DBus methods
// added to Cryptohome to use the "org.freedesktop.DBus.GLib.Async"
// annotation.  By using the annotation, it makes the calls compatible
// with the new chrome/dbus/dbus.h mechanisms.  It will make
// transitioning any new methods more straightforward and provide a means
// to transition existing methods in an incremental fashion.
//
// To transition a method, it will drop OUT_* types from its
// signature, and replace GError with DBusGMethodInvocation
// allowing the handling function to return immediately.
// Any method playing along will PostTask its work directly
// to the mount_thread_.  Upon completion, the method implementation
// will then need to perform a PostTask-equivalent call back to
// the main/DBus thread to issue its reply -- be it success or
// failure.  CryptohomeEventBase is used as a knock-off PostTask
// and the classes in this file provide the glue.
#ifndef CRYPTOHOME_DBUS_TRANSITION_H_
#define CRYPTOHOME_DBUS_TRANSITION_H_

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

#include <base/bind.h>
#include <base/bind_helpers.h>
#include <base/callback.h>
#include <brillo/glib/dbus.h>

#include "cryptohome/cryptohome_event_source.h"

namespace cryptohome {

extern const char* kDBusErrorReplyEventType;
extern const char* kDBusBlobReplyEventType;
extern const char* kDBusReplyEventType;

struct GErrorDeleter {
  inline void operator()(void* ptr) const {
    g_error_free(static_cast<GError*>(ptr));
  }
};

class DBusErrorReply : public CryptohomeEventBase {
 public:
  // Takes ownership of both pointers.
  DBusErrorReply(DBusGMethodInvocation* context, GError* error);
  virtual ~DBusErrorReply() { }
  virtual const char* GetEventName() const {
    return kDBusErrorReplyEventType;
  }
  virtual void Run() {
    dbus_g_method_return_error(context_, error_.get());
  }
  const GError& error() const { return *error_; }

 private:
  // If this event is not serviced, the memory will be leaked.
  DBusGMethodInvocation* context_;
  std::unique_ptr<GError, GErrorDeleter> error_;
};

class DBusBlobReply : public CryptohomeEventBase {
 public:
  // Ownership is taken for both pointers.
  DBusBlobReply(DBusGMethodInvocation* context, std::string* reply);
  virtual ~DBusBlobReply() {}
  virtual const char* GetEventName() const { return kDBusBlobReplyEventType; }
  virtual void Run() {
    brillo::glib::ScopedArray tmp_array(g_array_new(FALSE, FALSE, 1));
    g_array_append_vals(tmp_array.get(),
                        reply_->c_str(),
                        reply_->size());
    dbus_g_method_return(context_, tmp_array.get());
  }
  const std::string& reply() const { return *reply_; }

 private:
  // If this event is not serviced, the memory will be leaked.
  DBusGMethodInvocation* context_;
  std::unique_ptr<std::string> reply_;
};

// This class will allow glib-dbus method calls to be asynchronous.
// Note that this is only a temporary solution until glib-dbus is retired.
class DBusReply : public CryptohomeEventBase {
 public:
  template <typename... Params>
  DBusReply(base::OnceCallback<void(Params...)> cleanup_callback,
            DBusGMethodInvocation* context,
            Params... params) {
    cleanup_callback_ = base::BindOnce(std::move(cleanup_callback), params...);
    send_reply_ = base::BindOnce(
        [](DBusGMethodInvocation* context_to_send, Params... params_to_send) {
          dbus_g_method_return(context_to_send, params_to_send...);
        },
        context, params...);
  }

  // No output argument version
  explicit DBusReply(DBusGMethodInvocation* context) {
    cleanup_callback_ = base::DoNothing::Once();
    send_reply_ = base::BindOnce(
        [](DBusGMethodInvocation* context_to_send) {
          dbus_g_method_return(context_to_send);
        },
        context);
  }

  virtual ~DBusReply() {}

  virtual const char* GetEventName() const { return kDBusReplyEventType; }

  virtual void Run() {
    std::move(send_reply_).Run();
    std::move(cleanup_callback_).Run();
  }

 private:
  base::OnceClosure cleanup_callback_;
  base::OnceClosure send_reply_;
};

}  // namespace cryptohome

#endif  // CRYPTOHOME_DBUS_TRANSITION_H_
