#include <chrono>
#include <phosphor-logging/log.hpp>
#include <phosphor-logging/elog-errors.hpp>

#include "timer.hpp"
#include "xyz/openbmc_project/Common/error.hpp"

namespace phosphor
{
namespace network
{

using namespace phosphor::logging;
using namespace sdbusplus::xyz::openbmc_project::Common::Error;
// Initializes the timer object
void Timer::initialize()
{
    // This can not be called more than once.
    if (eventSource)
    {
        log<level::ERR>("Timer already initialized");
        elog<InternalFailure>();
    }

    auto r  = sd_event_default(&timeEvent);
    if (r < 0)
    {
        log<level::ERR>("Failure in creating the sd_event",
                        entry("ERROR=%d", r));

        elog<InternalFailure>();
    }

    // Add infinite expiration time
    r = sd_event_add_time(timeEvent,
                          &eventSource,
                          CLOCK_MONOTONIC, // Time base
                          UINT64_MAX,      // Expire time - way long time
                          0,               // Use default event accuracy
                          timeoutHandler,  // Callback handler on timeout
                          this);           // User data
    if (r < 0)
    {
        log<level::ERR>("Failure to set initial expiration time value",
                        entry("ERROR=%d", r));

        elog<InternalFailure>();
    }

    // Disable the timer for now
    r = setTimer(SD_EVENT_OFF);
    if (r < 0)
    {
        log<level::ERR>("Failure to disable timer",
                        entry("ERROR=%d", r));

        elog<InternalFailure>();
    }
    return;
}

/** @brief callback handler on timeout */
int Timer::timeoutHandler(sd_event_source* eventSource,
                          uint64_t usec, void* userData)
{
    auto timer = static_cast<Timer*>(userData);
    timer->expired = true;

    // Call optional user call back function if available
    if (timer->userCallBack)
    {
        timer->userCallBack();
    }

    log<level::INFO>("Timer expired");
    return 0;
}

// Gets the time from steady_clock
std::chrono::microseconds Timer::getTime()
{
    using namespace std::chrono;
    auto usec = steady_clock::now().time_since_epoch();
    return duration_cast<microseconds>(usec);
}

// Enables or disables the timer
int Timer::setTimer(int action)
{
    return sd_event_source_set_enabled(eventSource, action);
}

// Sets the time and arms the timer
int Timer::startTimer(std::chrono::microseconds timeValue)
{
    // Disable the timer
    setTimer(SD_EVENT_OFF);
    expired = false;

    // Get the current MONOTONIC time and add the delta
    auto expireTime = getTime() + timeValue;

    // Set the time
    auto r = sd_event_source_set_time(eventSource, expireTime.count());
    if (r < 0)
    {
        log<level::ERR>("Failure to set timer",
                        entry("ERROR=%d", r));

        elog<InternalFailure>();
    }

    // A ONESHOT timer means that when the timer goes off,
    // its moves to disabled state.
    r = setTimer(SD_EVENT_ONESHOT);
    if (r < 0)
    {
        log<level::ERR>("Failure to start timer",
                        entry("ERROR=%d", r));

        elog<InternalFailure>();
    }
    return r;
}

} // namespace network
} // namespace phosphor
