#pragma once

#include "data_types.hpp"

#include <sdbusplus/bus.hpp>
#include <sdbusplus/bus/match.hpp>
#include <sdbusplus/exception.hpp>
#include <sdbusplus/message.hpp>

#include <string>

struct Loop;

namespace phosphor
{
namespace dbus
{
namespace monitoring
{

/** @class SDBusPlus
 *  @brief DBus access delegate implementation for sdbusplus.
 */
class SDBusPlus
{
  private:
    static auto& getWatches()
    {
        static std::vector<sdbusplus::bus::match_t> watches;
        return watches;
    }

  public:
    static auto& getBus()
    {
        static auto bus = sdbusplus::bus::new_default();
        return bus;
    }

    /** @brief Invoke a method; ignore reply. */
    template <typename... Args>
    static void callMethodNoReply(const std::string& busName,
                                  const std::string& path,
                                  const std::string& interface,
                                  const std::string& method, Args&&... args)
    {
        auto reqMsg = getBus().new_method_call(
            busName.c_str(), path.c_str(), interface.c_str(), method.c_str());
        reqMsg.append(std::forward<Args>(args)...);
        getBus().call_noreply(reqMsg);

        // TODO: openbmc/openbmc#1719
        // invoke these methods async, with a callback
        // handler that checks for errors and logs.
    }

    /** @brief Invoke a method. */
    template <typename... Args>
    static auto callMethod(const std::string& busName, const std::string& path,
                           const std::string& interface,
                           const std::string& method, Args&&... args)
    {
        auto reqMsg = getBus().new_method_call(
            busName.c_str(), path.c_str(), interface.c_str(), method.c_str());
        reqMsg.append(std::forward<Args>(args)...);
        return getBus().call(reqMsg);
    }

    /** @brief Invoke a method and read the response. */
    template <typename Ret, typename... Args>
    static auto callMethodAndRead(const std::string& busName,
                                  const std::string& path,
                                  const std::string& interface,
                                  const std::string& method, Args&&... args)
    {
        Ret resp;
        sdbusplus::message_t respMsg = callMethod<Args...>(
            busName, path, interface, method, std::forward<Args>(args)...);
        try
        {
            respMsg.read(resp);
        }
        catch (const sdbusplus::exception_t& e)
        {
            // Empty responses are expected sometimes, and the calling
            // code is set up to handle it.
        }
        return resp;
    }

    /** @brief Register a DBus signal callback. */
    static auto addMatch(const std::string& match,
                         sdbusplus::bus::match_t::callback_t&& callback)
    {
        getWatches().emplace_back(getBus(), match, std::move(callback));
    }

    /** @brief Look up the bus name for a path and interface */
    static auto getBusName(const std::string& path,
                           const std::string& interface)
    {
        std::vector<std::string> interfaces{interface};
        std::string name;

        try
        {
            auto object = callMethodAndRead<GetObject>(
                MAPPER_BUSNAME, MAPPER_PATH, MAPPER_INTERFACE, "GetObject",
                path, interfaces);

            if (!object.empty())
            {
                name = object.begin()->first;
            }
        }
        catch (const sdbusplus::exception_t& e)
        {
            // Empty responses are expected sometimes, and the calling
            // code is set up to handle it.
        }
        return name;
    }

    friend Loop;
};

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