#pragma once

#include "config.h"

#include <sdbusplus/bus.hpp>
#include <sdeventplus/event.hpp>
#include <sdeventplus/utility/timer.hpp>
#include <xyz/openbmc_project/State/ScheduledHostTransition/server.hpp>

class TestScheduledHostTransition;

namespace phosphor
{
namespace state
{
namespace manager
{

using Transition =
    sdbusplus::xyz::openbmc_project::State::server::Host::Transition;
using ScheduledHostTransitionInherit = sdbusplus::server::object_t<
    sdbusplus::xyz::openbmc_project::State::server::ScheduledHostTransition>;

/** @class ScheduledHostTransition
 *  @brief Scheduled host transition implementation.
 *  @details A concrete implementation for
 *  xyz.openbmc_project.State.ScheduledHostTransition
 */
class ScheduledHostTransition : public ScheduledHostTransitionInherit
{
  public:
    ScheduledHostTransition(sdbusplus::bus_t& bus, const char* objPath,
                            size_t id, const sdeventplus::Event& event) :
        ScheduledHostTransitionInherit(
            bus, objPath, ScheduledHostTransition::action::defer_emit),
        bus(bus), id(id), event(event),
        timer(event, [this](auto&) { callback(); })
    {
        initialize();

        restoreScheduledValues();

        // We deferred this until we could get our property correct
        this->emit_object_added();
    }

    ~ScheduledHostTransition();

    /**
     * @brief Handle with scheduled time
     *
     * @param[in] value - The seconds since epoch
     * @return The time for the transition. It is the same as the input value if
     * it is set successfully. Otherwise, it won't return value, but throw an
     * error.
     **/
    uint64_t scheduledTime(uint64_t value) override;

  private:
    friend class TestScheduledHostTransition;

    /** @brief sdbusplus bus client connection */
    sdbusplus::bus_t& bus;

    /** @brief Host id. **/
    const size_t id = 0;

    /** @brief sdbusplus event */
    const sdeventplus::Event& event;

    /** @brief Timer used for host transition with seconds */
    sdeventplus::utility::Timer<sdeventplus::ClockId::RealTime> timer;

    /** @brief The fd for time change event */
    int timeFd = -1;

    /** @brief Get current time
     *
     *  @return - return current epoch time
     */
    std::chrono::seconds getTime();

    /** @brief Implement host transition
     *
     *  @return - Does not return anything. Error will result in exception
     *            being thrown
     */
    void hostTransition();

    /** @brief Used by the timer to do host transition */
    void callback();

    /** @brief Initialize timerFd related resource */
    void initialize();

    /** @brief The callback function on system time change
     *
     * @param[in] es - Source of the event
     * @param[in] fd - File descriptor of the timer
     * @param[in] revents - Not used
     * @param[in] userdata - User data pointer
     */
    static int onTimeChange(sd_event_source* es, int fd, uint32_t revents,
                            void* userdata);

    /** @brief The deleter of sd_event_source */
    std::function<void(sd_event_source*)> sdEventSourceDeleter =
        [](sd_event_source* p) {
            if (p)
            {
                sd_event_source_unref(p);
            }
        };

    using SdEventSource =
        std::unique_ptr<sd_event_source, decltype(sdEventSourceDeleter)>;

    /** @brief The event source on system time change */
    SdEventSource timeChangeEventSource{nullptr, sdEventSourceDeleter};

    /** @brief Handle with the process when bmc time is changed*/
    void handleTimeUpdates();

    /** @brief Serialize the scheduled values */
    void serializeScheduledValues();

    /** @brief Deserialize the scheduled values
     *
     *  @param[out] time - Deserialized scheduled time
     *  @param[out] trans - Deserialized requested transition
     *
     *  @return bool - true if successful, false otherwise
     */
    bool deserializeScheduledValues(uint64_t& time, Transition& trans);

    /** @brief Restore scheduled time and requested transition from persisted
     * file */
    void restoreScheduledValues();
};
} // namespace manager
} // namespace state
} // namespace phosphor
