#pragma once

#include <chrono>
#include <memory>
#include <systemd/sd-event.h>

// TODO: openbmc/openbmc#1720 - add error handling for sd_event API failures

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

/** @class Source
 *  @brief Provides C++ bindings to the sd_event_source* functions.
 */
class Source
{
  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;
        sd_event_source_get_enabled(src.get(), &enabled);
        return enabled;
    }

    /** @brief Allow the source to generate events. */
    void enable(int enable)
    {
        sd_event_source_set_enabled(src.get(), enable);
    }

    /** @brief Set the expiration on a timer source. */
    void setTime(const std::chrono::steady_clock::time_point& expires)
    {
        using namespace std::chrono;
        auto epoch = expires.time_since_epoch();
        auto time = duration_cast<microseconds>(epoch);
        sd_event_source_set_time(src.get(), time.count());
    }

    /** @brief Get the expiration on a timer source. */
    auto getTime()
    {
        using namespace std::chrono;
        uint64_t usec;
        sd_event_source_get_time(src.get(), &usec);
        microseconds d(usec);
        return steady_clock::time_point(d);
    }

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