#pragma once

#include <memory>
#include <climits>
#include <systemd/sd-bus.h>
#include <sdbusplus/message.hpp>

namespace sdbusplus
{

// Forward declare.
namespace server { namespace interface { struct interface; } }
namespace server { namespace manager { struct manager; } }
namespace server { namespace object { template<class...> struct object; } }
namespace server { namespace match { struct match; } }

namespace bus
{

using busp_t = sd_bus*;
class bus;

/** @brief Get an instance of the 'default' bus. */
bus new_default();
/** @brief Get an instance of the 'user' session bus. */
bus new_user();
/** @brief Get an instance of the 'system' bus. */
bus new_system();

namespace details
{

/** @brief unique_ptr functor to release a bus reference. */
struct BusDeleter
{
    void operator()(sd_bus* ptr) const
    {
        sd_bus_unref(ptr);
    }
};

/* @brief Alias 'bus' to a unique_ptr type for auto-release. */
using bus = std::unique_ptr<sd_bus, BusDeleter>;

} // namespace details

/** @class bus
 *  @brief Provides C++ bindings to the sd_bus_* class functions.
 */
struct bus
{
        /* Define all of the basic class operations:
         *     Not allowed:
         *         - Default constructor to avoid nullptrs.
         *         - Copy operations due to internal unique_ptr.
         *     Allowed:
         *         - Move operations.
         *         - Destructor.
         */
    bus() = delete;
    bus(const bus&) = delete;
    bus& operator=(const bus&) = delete;
    bus(bus&&) = default;
    bus& operator=(bus&&) = default;
    ~bus() = default;

    /** @brief Conversion constructor from 'busp_t'.
     *
     *  Takes ownership of the bus-pointer and releases it when done.
     */
    explicit bus(busp_t b) : _bus(b) {}

    /** @brief Release ownership of the stored bus-pointer. */
    busp_t release() { return _bus.release(); }

    /** @brief Wait for new dbus messages or signals.
     *
     *  @param[in] timeout_us - Timeout in usec.
     */
    void wait(uint64_t timeout_us = ULLONG_MAX)
    {
        sd_bus_wait(_bus.get(), timeout_us);
    }

    /** @brief Process waiting dbus messages or signals. */
    auto process()
    {
        sd_bus_message* m = nullptr;
        sd_bus_process(_bus.get(), &m);

        return message::message(m, std::false_type());
    }

    /** @brief Process waiting dbus messages or signals, discarding unhandled.
     */
    void process_discard()
    {
        sd_bus_process(_bus.get(), nullptr);
    }

    /** @brief Claim a service name on the dbus.
     *
     *  @param[in] service - The service name to claim.
     */
    void request_name(const char* service)
    {
        sd_bus_request_name(_bus.get(), service, 0);
    }

    /** @brief Create a method_call message.
     *
     *  @param[in] service - The service to call.
     *  @param[in] objpath - The object's path for the call.
     *  @param[in] interf - The object's interface to call.
     *  @param[in] method - The object's method to call.
     *
     *  @return A newly constructed message.
     */
    auto new_method_call(const char* service, const char* objpath,
                         const char* interf, const char* method)
    {
        sd_bus_message* m = nullptr;
        sd_bus_message_new_method_call(_bus.get(), &m, service, objpath,
                                       interf, method);

        return message::message(m, std::false_type());
    }

    /** @brief Create a signal message.
     *
     *  @param[in] objpath - The object's path for the signal.
     *  @param[in] interf - The object's interface for the signal.
     *  @param[in] member - The signal name.
     *
     *  @return A newly constructed message.
     */
    auto new_signal(const char* objpath, const char* interf, const char* member)
    {
        sd_bus_message* m = nullptr;
        sd_bus_message_new_signal(_bus.get(), &m, objpath, interf, member);

        return message::message(m, std::false_type());
    }

    /** @brief Perform a message call.
     *
     *  @param[in] m - The method_call message.
     *  @param[in] timeout_us - The timeout for the method call.
     *
     *  @return The response message.
     */
    auto call(message::message& m, uint64_t timeout_us = 0)
    {
        sd_bus_message* reply = nullptr;
        sd_bus_call(_bus.get(), m.get(), timeout_us, nullptr, &reply);

        return message::message(reply, std::false_type());
    }

    /** @brief Perform a message call, ignoring the reply.
     *
     *  @param[in] m - The method_call message.
     *  @param[in] timeout_us - The timeout for the method call.
     */
    void call_noreply(message::message& m, uint64_t timeout_us = 0)
    {
        sd_bus_call(_bus.get(), m.get(), timeout_us, nullptr, nullptr);
    }

    /** @brief Get the bus unique name. Ex: ":1.11".
      *
      * @return The bus unique name.
      */
    auto get_unique_name()
    {
        const char* unique = nullptr;
        sd_bus_get_unique_name(_bus.get(), &unique);
        return std::string(unique);
    }

    friend struct server::interface::interface;
    friend struct server::manager::manager;
    template<class... Args> friend struct server::object::object;
    friend struct server::match::match;

    private:
        busp_t get() { return _bus.get(); }
        details::bus _bus;
};

inline bus new_default()
{
    sd_bus* b = nullptr;
    sd_bus_open(&b);
    return bus(b);
}

inline bus new_user()
{
    sd_bus* b = nullptr;
    sd_bus_open_user(&b);
    return bus(b);
}

inline bus new_system()
{
    sd_bus* b = nullptr;
    sd_bus_open_system(&b);
    return bus(b);
}

} // namespace bus

/** @brief Get the dbus bus from the message.
 *
 *  @return The dbus bus.
 */
inline auto message::message::get_bus()
{
    sd_bus* b = nullptr;
    b = sd_bus_message_get_bus(_msg.get());
    return bus::bus(sd_bus_ref(b));
}

} // namespace sdbusplus
