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

// This file provides internal implementation details of dispatching D-Bus
// method calls to a D-Bus object methods by reading the expected parameter
// values from D-Bus message buffer then invoking a native C++ callback with
// those parameters passed in. If the callback returns a value, that value is
// sent back to the caller of D-Bus method via the response message.

// This is achieved by redirecting the parsing of parameter values from D-Bus
// message buffer to DBusParamReader helper class.
// DBusParamReader de-serializes the parameter values from the D-Bus message
// and calls the provided native C++ callback with those arguments.
// However it expects the callback with a simple signature like this:
//    void callback(Args...);
// The method handlers for DBusObject, on the other hand, have one of the
// following signatures:
//    void handler(Args...);
//    ReturnType handler(Args...);
//    bool handler(ErrorPtr* error, Args...);
//    void handler(std::unique_ptr<DBusMethodResponse<T1, T2,...>>, Args...);
//
// To make this all work, we craft a simple callback suitable for
// DBusParamReader using a lambda in DBusInvoker::Invoke() and redirect the call
// to the appropriate method handler using additional data captured by the
// lambda object.

#ifndef LIBBRILLO_BRILLO_DBUS_DBUS_OBJECT_INTERNAL_IMPL_H_
#define LIBBRILLO_BRILLO_DBUS_DBUS_OBJECT_INTERNAL_IMPL_H_

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

#include <brillo/dbus/data_serialization.h>
#include <brillo/dbus/dbus_method_response.h>
#include <brillo/dbus/dbus_param_reader.h>
#include <brillo/dbus/dbus_param_writer.h>
#include <brillo/dbus/utils.h>
#include <brillo/errors/error.h>
#include <dbus/message.h>

namespace brillo {
namespace dbus_utils {

// This is an abstract base class to allow dispatching a native C++ callback
// method when a corresponding D-Bus method is called.
class DBusInterfaceMethodHandlerInterface {
 public:
  virtual ~DBusInterfaceMethodHandlerInterface() = default;

  // Returns true if the method has been handled synchronously (whether or not
  // a success or error response message had been sent).
  virtual void HandleMethod(::dbus::MethodCall* method_call,
                            ResponseSender sender) = 0;
};

// This is a special implementation of DBusInterfaceMethodHandlerInterface for
// extremely simple synchronous method handlers that cannot possibly fail
// (that is, they do not send an error response).
// The handler is expected to take an arbitrary number of arguments of type
// |Args...| which can contain both inputs (passed in by value or constant
// reference) and outputs (passed in as pointers)...
// It may also return a single value of type R (or could be a void function if
// no return value is to be sent to the caller). If the handler has a return
// value, then it cannot have any output parameters in its parameter list.
// The signature of the callback handler is expected to be:
//    R(Args...)
template <typename R, typename... Args>
class SimpleDBusInterfaceMethodHandler
    : public DBusInterfaceMethodHandlerInterface {
 public:
  // A constructor that takes a |handler| to be called when HandleMethod()
  // virtual function is invoked.
  explicit SimpleDBusInterfaceMethodHandler(
      const base::Callback<R(Args...)>& handler)
      : handler_(handler) {}
  SimpleDBusInterfaceMethodHandler(const SimpleDBusInterfaceMethodHandler&) =
      delete;
  SimpleDBusInterfaceMethodHandler& operator=(
      const SimpleDBusInterfaceMethodHandler&) = delete;

  void HandleMethod(::dbus::MethodCall* method_call,
                    ResponseSender sender) override {
    DBusMethodResponse<R> method_response(method_call, std::move(sender));
    auto invoke_callback = [this, &method_response](const Args&... args) {
      method_response.Return(handler_.Run(args...));
    };

    ErrorPtr param_reader_error;
    ::dbus::MessageReader reader(method_call);
    // The handler is expected a return value, don't allow output parameters.
    if (!DBusParamReader<false, Args...>::Invoke(invoke_callback, &reader,
                                                 &param_reader_error)) {
      // Error parsing method arguments.
      method_response.ReplyWithError(param_reader_error.get());
    }
  }

 private:
  // C++ callback to be called when a DBus method is dispatched.
  base::Callback<R(Args...)> handler_;
};

// Specialization of SimpleDBusInterfaceMethodHandlerInterface for
// R=void (methods with no return values).
template <typename... Args>
class SimpleDBusInterfaceMethodHandler<void, Args...>
    : public DBusInterfaceMethodHandlerInterface {
 public:
  // A constructor that takes a |handler| to be called when HandleMethod()
  // virtual function is invoked.
  explicit SimpleDBusInterfaceMethodHandler(
      const base::Callback<void(Args...)>& handler)
      : handler_(handler) {}
  SimpleDBusInterfaceMethodHandler(const SimpleDBusInterfaceMethodHandler&) =
      delete;
  SimpleDBusInterfaceMethodHandler& operator=(
      const SimpleDBusInterfaceMethodHandler&) = delete;

  void HandleMethod(::dbus::MethodCall* method_call,
                    ResponseSender sender) override {
    DBusMethodResponseBase method_response(method_call, std::move(sender));
    auto invoke_callback = [this, &method_response](const Args&... args) {
      handler_.Run(args...);
      auto response = method_response.CreateCustomResponse();
      ::dbus::MessageWriter writer(response.get());
      DBusParamWriter::AppendDBusOutParams(&writer, args...);
      method_response.SendRawResponse(std::move(response));
    };

    ErrorPtr param_reader_error;
    ::dbus::MessageReader reader(method_call);
    if (!DBusParamReader<true, Args...>::Invoke(invoke_callback, &reader,
                                                &param_reader_error)) {
      // Error parsing method arguments.
      method_response.ReplyWithError(param_reader_error.get());
    }
  }

 private:
  // C++ callback to be called when a DBus method is dispatched.
  base::Callback<void(Args...)> handler_;
};

// An implementation of DBusInterfaceMethodHandlerInterface for simple
// synchronous method handlers that may fail and return an error response
// message.
// The handler is expected to take an arbitrary number of arguments of type
// |Args...| which can contain both inputs (passed in by value or constant
// reference) and outputs (passed in as pointers)...
// In case of an error, the handler must return false and set the error details
// into the |error| object provided.
// The signature of the callback handler is expected to be:
//    bool(ErrorPtr*, Args...)
template <typename... Args>
class SimpleDBusInterfaceMethodHandlerWithError
    : public DBusInterfaceMethodHandlerInterface {
 public:
  // A constructor that takes a |handler| to be called when HandleMethod()
  // virtual function is invoked.
  explicit SimpleDBusInterfaceMethodHandlerWithError(
      const base::Callback<bool(ErrorPtr*, Args...)>& handler)
      : handler_(handler) {}
  SimpleDBusInterfaceMethodHandlerWithError(
      const SimpleDBusInterfaceMethodHandlerWithError&) = delete;
  SimpleDBusInterfaceMethodHandlerWithError& operator=(
      const SimpleDBusInterfaceMethodHandlerWithError&) = delete;

  void HandleMethod(::dbus::MethodCall* method_call,
                    ResponseSender sender) override {
    DBusMethodResponseBase method_response(method_call, std::move(sender));
    auto invoke_callback = [this, &method_response](const Args&... args) {
      ErrorPtr error;
      if (!handler_.Run(&error, args...)) {
        method_response.ReplyWithError(error.get());
      } else {
        auto response = method_response.CreateCustomResponse();
        ::dbus::MessageWriter writer(response.get());
        DBusParamWriter::AppendDBusOutParams(&writer, args...);
        method_response.SendRawResponse(std::move(response));
      }
    };

    ErrorPtr param_reader_error;
    ::dbus::MessageReader reader(method_call);
    if (!DBusParamReader<true, Args...>::Invoke(invoke_callback, &reader,
                                                &param_reader_error)) {
      // Error parsing method arguments.
      method_response.ReplyWithError(param_reader_error.get());
    }
  }

 private:
  // C++ callback to be called when a DBus method is dispatched.
  base::Callback<bool(ErrorPtr*, Args...)> handler_;
};

// An implementation of SimpleDBusInterfaceMethodHandlerWithErrorAndMessage
// which is almost identical to SimpleDBusInterfaceMethodHandlerWithError with
// the exception that the callback takes an additional parameter - raw D-Bus
// message used to invoke the method handler.
// The handler is expected to take an arbitrary number of arguments of type
// |Args...| which can contain both inputs (passed in by value or constant
// reference) and outputs (passed in as pointers)...
// In case of an error, the handler must return false and set the error details
// into the |error| object provided.
// The signature of the callback handler is expected to be:
//    bool(ErrorPtr*, dbus::Message*, Args...)
template <typename... Args>
class SimpleDBusInterfaceMethodHandlerWithErrorAndMessage
    : public DBusInterfaceMethodHandlerInterface {
 public:
  // A constructor that takes a |handler| to be called when HandleMethod()
  // virtual function is invoked.
  explicit SimpleDBusInterfaceMethodHandlerWithErrorAndMessage(
      const base::Callback<bool(ErrorPtr*, ::dbus::Message*, Args...)>& handler)
      : handler_(handler) {}
  SimpleDBusInterfaceMethodHandlerWithErrorAndMessage(
      const SimpleDBusInterfaceMethodHandlerWithErrorAndMessage&) = delete;
  SimpleDBusInterfaceMethodHandlerWithErrorAndMessage& operator=(
      const SimpleDBusInterfaceMethodHandlerWithErrorAndMessage&) = delete;

  void HandleMethod(::dbus::MethodCall* method_call,
                    ResponseSender sender) override {
    DBusMethodResponseBase method_response(method_call, std::move(sender));
    auto invoke_callback = [this, method_call,
                            &method_response](const Args&... args) {
      ErrorPtr error;
      if (!handler_.Run(&error, method_call, args...)) {
        method_response.ReplyWithError(error.get());
      } else {
        auto response = method_response.CreateCustomResponse();
        ::dbus::MessageWriter writer(response.get());
        DBusParamWriter::AppendDBusOutParams(&writer, args...);
        method_response.SendRawResponse(std::move(response));
      }
    };

    ErrorPtr param_reader_error;
    ::dbus::MessageReader reader(method_call);
    if (!DBusParamReader<true, Args...>::Invoke(invoke_callback, &reader,
                                                &param_reader_error)) {
      // Error parsing method arguments.
      method_response.ReplyWithError(param_reader_error.get());
    }
  }

 private:
  // C++ callback to be called when a DBus method is dispatched.
  base::Callback<bool(ErrorPtr*, ::dbus::Message*, Args...)> handler_;
};

// An implementation of DBusInterfaceMethodHandlerInterface for more generic
// (and possibly asynchronous) method handlers. The handler is expected
// to take an arbitrary number of input arguments of type |Args...| and send
// the method call response (including a possible error response) using
// the provided DBusMethodResponse object.
// The signature of the callback handler is expected to be:
//    void(std::unique_ptr<DBusMethodResponse<RetTypes...>, Args...)
template <typename Response, typename... Args>
class DBusInterfaceMethodHandler : public DBusInterfaceMethodHandlerInterface {
 public:
  // A constructor that takes a |handler| to be called when HandleMethod()
  // virtual function is invoked.
  explicit DBusInterfaceMethodHandler(
      const base::Callback<void(std::unique_ptr<Response>, Args...)>& handler)
      : handler_(handler) {}
  DBusInterfaceMethodHandler(const DBusInterfaceMethodHandler&) = delete;
  DBusInterfaceMethodHandler& operator=(const DBusInterfaceMethodHandler&) =
      delete;

  // This method forwards the call to |handler_| after extracting the required
  // arguments from the DBus message buffer specified in |method_call|.
  // The output parameters of |handler_| (if any) are sent back to the called.
  void HandleMethod(::dbus::MethodCall* method_call,
                    ResponseSender sender) override {
    auto invoke_callback = [this, method_call, &sender](const Args&... args) {
      auto response =
          std::make_unique<Response>(method_call, std::move(sender));
      handler_.Run(std::move(response), args...);
    };

    ErrorPtr param_reader_error;
    ::dbus::MessageReader reader(method_call);
    if (!DBusParamReader<false, Args...>::Invoke(invoke_callback, &reader,
                                                 &param_reader_error)) {
      // Error parsing method arguments.
      DBusMethodResponseBase method_response(method_call, std::move(sender));
      method_response.ReplyWithError(param_reader_error.get());
    }
  }

 private:
  // C++ callback to be called when a D-Bus method is dispatched.
  base::Callback<void(std::unique_ptr<Response>, Args...)> handler_;
};

// An implementation of DBusInterfaceMethodHandlerWithMessage which is almost
// identical to AddSimpleMethodHandlerWithError with the exception that the
// callback takes an additional parameter - raw D-Bus message.
// The handler is expected to take an arbitrary number of input arguments of
// type |Args...| and send the method call response (including a possible error
// response) using the provided DBusMethodResponse object.
// The signature of the callback handler is expected to be:
//    void(std::unique_ptr<DBusMethodResponse<RetTypes...>, dbus::Message*,
//         Args...);
template <typename Response, typename... Args>
class DBusInterfaceMethodHandlerWithMessage
    : public DBusInterfaceMethodHandlerInterface {
 public:
  // A constructor that takes a |handler| to be called when HandleMethod()
  // virtual function is invoked.
  explicit DBusInterfaceMethodHandlerWithMessage(
      const base::Callback<
          void(std::unique_ptr<Response>, ::dbus::Message*, Args...)>& handler)
      : handler_(handler) {}
  DBusInterfaceMethodHandlerWithMessage(
      const DBusInterfaceMethodHandlerWithMessage&) = delete;
  DBusInterfaceMethodHandlerWithMessage& operator=(
      const DBusInterfaceMethodHandlerWithMessage&) = delete;

  // This method forwards the call to |handler_| after extracting the required
  // arguments from the DBus message buffer specified in |method_call|.
  // The output parameters of |handler_| (if any) are sent back to the called.
  void HandleMethod(::dbus::MethodCall* method_call,
                    ResponseSender sender) override {
    auto invoke_callback = [this, method_call, &sender](const Args&... args) {
      auto response =
          std::make_unique<Response>(method_call, std::move(sender));
      handler_.Run(std::move(response), method_call, args...);
    };

    ErrorPtr param_reader_error;
    ::dbus::MessageReader reader(method_call);
    if (!DBusParamReader<false, Args...>::Invoke(invoke_callback, &reader,
                                                 &param_reader_error)) {
      // Error parsing method arguments.
      DBusMethodResponseBase method_response(method_call, std::move(sender));
      method_response.ReplyWithError(param_reader_error.get());
    }
  }

 private:
  // C++ callback to be called when a D-Bus method is dispatched.
  base::Callback<void(std::unique_ptr<Response>, ::dbus::Message*, Args...)>
      handler_;
};

// An implementation of DBusInterfaceMethodHandlerInterface that has custom
// processing of both input and output parameters. This class is used by
// DBusObject::AddRawMethodHandler and expects the callback to be of the
// following signature:
//    void(dbus::MethodCall*, ResponseSender)
// It will be up to the callback to parse the input parameters from the
// message buffer and construct the D-Bus Response object.
class RawDBusInterfaceMethodHandler
    : public DBusInterfaceMethodHandlerInterface {
 public:
  // A constructor that takes a |handler| to be called when HandleMethod()
  // virtual function is invoked.
  RawDBusInterfaceMethodHandler(
      const base::Callback<void(::dbus::MethodCall*, ResponseSender)>& handler)
      : handler_(handler) {}
  RawDBusInterfaceMethodHandler(const RawDBusInterfaceMethodHandler&) = delete;
  RawDBusInterfaceMethodHandler& operator=(
      const RawDBusInterfaceMethodHandler&) = delete;

  void HandleMethod(::dbus::MethodCall* method_call,
                    ResponseSender sender) override {
    handler_.Run(method_call, std::move(sender));
  }

 private:
  // C++ callback to be called when a D-Bus method is dispatched.
  base::Callback<void(::dbus::MethodCall*, ResponseSender)> handler_;
};

}  // namespace dbus_utils
}  // namespace brillo

#endif  // LIBBRILLO_BRILLO_DBUS_DBUS_OBJECT_INTERNAL_IMPL_H_
