#include <chrono>
#include <phosphor-logging/log.hpp>
#include "watchdog.hpp"
namespace phosphor
{
namespace watchdog
{
using namespace std::chrono;
using namespace std::chrono_literals;
using namespace phosphor::logging;

// systemd service to kick start a target.
constexpr auto SYSTEMD_SERVICE    = "org.freedesktop.systemd1";
constexpr auto SYSTEMD_ROOT       = "/org/freedesktop/systemd1";
constexpr auto SYSTEMD_INTERFACE  = "org.freedesktop.systemd1.Manager";

// Enable or disable watchdog
bool Watchdog::enabled(bool value)
{
    if (this->enabled() != value)
    {
        if (value)
        {
            // Start ONESHOT timer. Timer handles all in usec
            auto usec = duration_cast<microseconds>(
                                      milliseconds(this->interval()));
            // Update new expiration
            timer.start(usec);

            // Enable timer
            timer.setEnabled<std::true_type>();

            log<level::INFO>("watchdog: enabled and started",
                             entry("INTERVAL=%llu", this->interval()));
        }
        else
        {
            timer.setEnabled<std::false_type>();
            timer.clearExpired();
            log<level::INFO>("watchdog: disabled");
        }
    }
    return WatchdogInherits::enabled(value);
}

// Get the remaining time before timer expires.
// If the timer is disabled, returns 0
uint64_t Watchdog::timeRemaining() const
{
    uint64_t timeRemain = 0;

    if (this->enabled())
    {
        // timer may have already expired and disabled
        if (timer.getEnabled() != SD_EVENT_OFF)
        {
            // the one-shot timer does not expire yet
            auto expiry = duration_cast<milliseconds>(
                                   timer.getRemaining());

            // convert to msec per interface expectation.
            auto timeNow = duration_cast<milliseconds>(
                                    Timer::getCurrentTime());

            // Its possible that timer may have expired by now.
            // So need to cross verify.
            timeRemain = (expiry > timeNow) ?
                            (expiry - timeNow).count() : 0;
        }
    }
    return timeRemain;
}

// Reset the timer to a new expiration value
uint64_t Watchdog::timeRemaining(uint64_t value)
{
    if (this->enabled())
    {
        // Disable the timer
        timer.setEnabled<std::false_type>();

        // Timer handles all in microseconds and hence converting
        auto usec = duration_cast<microseconds>(
                                  milliseconds(value));
        // Update new expiration
        timer.start(usec);

        // Enable the timer.
        timer.setEnabled<std::true_type>();

        // Update Interval in Base class.
        this->interval(value);

        // Update Base class data.
        return WatchdogInherits::timeRemaining(value);
    }
    return 0;
}

// Optional callback function on timer expiration
void Watchdog::timeOutHandler()
{
    if (!target.empty())
    {
        auto method = bus.new_method_call(SYSTEMD_SERVICE,
                                          SYSTEMD_ROOT,
                                          SYSTEMD_INTERFACE,
                                          "StartUnit");
        method.append(target);
        method.append("replace");

        bus.call_noreply(method);
    }
    return;
}

} // namespace watchdog
} // namepsace phosphor
