#pragma once

#include "callback.hpp"

#include <phosphor-logging/log.hpp>

#include <experimental/tuple>
#include <string>
#include <tuple>

namespace phosphor
{
namespace dbus
{
namespace monitoring
{
namespace detail
{

using namespace phosphor::logging;

/** @class CallDBusMethod
 *  @brief Provide explicit call forwarding to
 *     DBusInterface::callMethodNoReply.
 *
 *  @tparam DBusInterface - The DBus interface to use.
 *  @tparam MethodArgs - DBus method argument types.
 */
template <typename DBusInterface, typename... MethodArgs>
struct CallDBusMethod
{
    static void op(const std::string& bus, const std::string& path,
                   const std::string& iface, const std::string& method,
                   MethodArgs&&... args)
    {
        try
        {
            DBusInterface::callMethodNoReply(bus, path, iface, method,
                                             std::forward<MethodArgs>(args)...);
        }
        catch (const sdbusplus::exception::exception& e)
        {
            // clang-format off
            log<level::ERR>("Unable to call DBus method",
                            entry("BUS=%s", bus.c_str(),
                                  "PATH=%s", path.c_str(),
                                  "IFACE=%s", iface.c_str(),
                                  "METHOD=%s", method.c_str(),
                                  "ERROR=%s", e.what()));
            // clang-format on
        }
    }
};
} // namespace detail

/** @class MethodBase
 *  @brief Invoke DBus method callback implementation.
 *
 *  The method callback invokes the client supplied DBus method.
 */
class MethodBase : public Callback
{
  public:
    MethodBase() = delete;
    MethodBase(const MethodBase&) = delete;
    MethodBase(MethodBase&&) = default;
    MethodBase& operator=(const MethodBase&) = delete;
    MethodBase& operator=(MethodBase&&) = default;
    virtual ~MethodBase() = default;
    MethodBase(const std::string& b, const std::string& p, const std::string& i,
               const std::string& m) :
        Callback(),
        bus(b), path(p), interface(i), method(m)
    {}

    /** @brief Callback interface implementation. */
    void operator()(Context ctx) override = 0;

  protected:
    const std::string& bus;
    const std::string& path;
    const std::string& interface;
    const std::string& method;
};

/** @class Method
 *  @brief C++ type specific logic for the method callback.
 *
 *  @tparam DBusInterface - The DBus interface to use to call the method.
 *  @tparam MethodArgs - DBus method argument types.
 */
template <typename DBusInterface, typename... MethodArgs>
class Method : public MethodBase
{
  public:
    Method() = delete;
    Method(const Method&) = default;
    Method(Method&&) = default;
    Method& operator=(const Method&) = default;
    Method& operator=(Method&&) = default;
    ~Method() = default;
    Method(const std::string& bus, const std::string& path,
           const std::string& iface, const std::string& method,
           MethodArgs&&... arguments) :
        MethodBase(bus, path, iface, method),
        args(std::forward<MethodArgs>(arguments)...)
    {}

    /** @brief Callback interface implementation. */
    void operator()(Context ctx) override
    {
        std::apply(detail::CallDBusMethod<DBusInterface, MethodArgs...>::op,
                   std::tuple_cat(std::make_tuple(bus), std::make_tuple(path),
                                  std::make_tuple(interface),
                                  std::make_tuple(method), args));
    }

  private:
    std::tuple<MethodArgs...> args;
};

/** @brief Argument type deduction for constructing Method instances. */
template <typename DBusInterface, typename... MethodArgs>
auto makeMethod(const std::string& bus, const std::string& path,
                const std::string& iface, const std::string& method,
                MethodArgs&&... arguments)
{
    return std::make_unique<Method<DBusInterface, MethodArgs...>>(
        bus, path, iface, method, std::forward<MethodArgs>(arguments)...);
}

} // namespace monitoring
} // namespace dbus
} // namespace phosphor
