#pragma once

#include <memory>
#include <phosphor-logging/elog.hpp>
#include <phosphor-logging/elog-errors.hpp>
#include <systemd/sd-event.h>
#include <xyz/openbmc_project/Common/error.hpp>

namespace sdevent
{
namespace source
{

using SourcePtr = sd_event_source*;

namespace details
{

/** @brief unique_ptr functor to release a source reference. */
struct SourceDeleter
{
    void operator()(sd_event_source* ptr) const
    {
        deleter(ptr);
    }

    decltype(&sd_event_source_unref) deleter = sd_event_source_unref;
};

/* @brief Alias 'source' to a unique_ptr type for auto-release. */
using source = std::unique_ptr<sd_event_source, SourceDeleter>;

} // namespace details

using namespace phosphor::logging;

/** @class Source
 *  @brief Provides C++ bindings to the sd_event_source* functions.
 */
class Source
{
    private:
        using InternalFailure = sdbusplus::xyz::openbmc_project::Common::
            Error::InternalFailure;

    public:
        /* 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.
         */
        Source() = delete;
        Source(const Source&) = delete;
        Source& operator=(const Source&) = delete;
        Source(Source&&) = default;
        Source& operator=(Source&&) = default;
        ~Source() = default;

        /** @brief Conversion constructor from 'SourcePtr'.
         *
         *  Increments ref-count of the source-pointer and releases it
         *  when done.
         */
        explicit Source(SourcePtr s) : src(sd_event_source_ref(s)) {}

        /** @brief Constructor for 'source'.
         *
         *  Takes ownership of the source-pointer and releases it when done.
         */
        Source(SourcePtr s, std::false_type) : src(s) {}

        /** @brief Check if source contains a real pointer. (non-nullptr). */
        explicit operator bool() const
        {
            return bool(src);
        }

        /** @brief Test whether or not the source can generate events. */
        auto enabled()
        {
            int enabled;
            auto rc = sd_event_source_get_enabled(src.get(), &enabled);
            if (rc < 0)
            {
                log<level::ERR>("Error in call to sd_event_source_get_enabled",
                        entry("RC=%d", rc));
                elog<InternalFailure>();
            }

            return enabled;
        }

        /** @brief Allow the source to generate events. */
        void enable(int enable)
        {
            auto rc = sd_event_source_set_enabled(src.get(), enable);
            if (rc < 0)
            {
                log<level::ERR>("Error in call to sd_event_source_set_enabled",
                        entry("RC=%d", rc),
                        entry("ENABLE=%d", enable));
                elog<InternalFailure>();
            }
        }

    private:
        details::source src;
};
} // namespace source
} // namespace sdevent
