#include <sdbusplus/timer.hpp>

#include <chrono>
#include <iostream>

#include <gtest/gtest.h>

using namespace phosphor;

class TimerTest : public ::testing::Test
{
  public:
    // systemd event handler
    sd_event* events = nullptr;

    // Need this so that events can be initialized.
    int rc;

    // Source of event
    sd_event_source* eventSource = nullptr;

    // Add a Timer Object
    Timer timer;

    // Gets called as part of each TEST_F construction
    TimerTest() : rc(sd_event_default(&events)), timer(events)
    {
        // Check for successful creation of
        // event handler and timer object.
        EXPECT_GE(rc, 0);
    }

    // Gets called as part of each TEST_F destruction
    ~TimerTest()
    {
        events = sd_event_unref(events);
    }
};

class TimerTestCallBack : public ::testing::Test
{
  public:
    // systemd event handler
    sd_event* events;

    // Need this so that events can be initialized.
    int rc;

    // Source of event
    sd_event_source* eventSource = nullptr;

    // Add a Timer Object
    std::unique_ptr<Timer> timer = nullptr;

    // Indicates optional call back fun was called
    bool callBackDone = false;

    void callBack()
    {
        callBackDone = true;
    }

    // Gets called as part of each TEST_F construction
    TimerTestCallBack() : rc(sd_event_default(&events))

    {
        // Check for successful creation of
        // event handler and timer object.
        EXPECT_GE(rc, 0);

        std::function<void()> func(
            std::bind(&TimerTestCallBack::callBack, this));
        timer = std::make_unique<Timer>(events, func);
    }

    // Gets called as part of each TEST_F destruction
    ~TimerTestCallBack()
    {
        events = sd_event_unref(events);
    }
};

/** @brief Makes sure that timer is expired and the
 *  callback handler gets invoked post 2 seconds
 */
TEST_F(TimerTest, timerExpiresAfter2seconds)
{
    using namespace std::chrono;

    auto time = duration_cast<microseconds>(seconds(2));
    EXPECT_GE(timer.start(time), 0);

    // Waiting 2 seconds is enough here since we have
    // already spent some usec now
    int count = 0;
    while (count < 2 && !timer.isExpired())
    {
        // Returns -0- on timeout and positive number on dispatch
        auto sleepTime = duration_cast<microseconds>(seconds(1));
        if (!sd_event_run(events, sleepTime.count()))
        {
            count++;
        }
    }
    EXPECT_EQ(true, timer.isExpired());
    EXPECT_EQ(1, count);
}

/** @brief Makes sure that timer is not expired
 */
TEST_F(TimerTest, timerNotExpiredAfter2Seconds)
{
    using namespace std::chrono;

    auto time = duration_cast<microseconds>(seconds(2));
    EXPECT_GE(timer.start(time), 0);

    // Now turn off the timer post a 1 second sleep
    sleep(1);
    EXPECT_GE(timer.stop(), 0);

    // Wait 2 seconds and see that timer is not expired
    int count = 0;
    while (count < 2)
    {
        // Returns -0- on timeout
        auto sleepTime = duration_cast<microseconds>(seconds(1));
        if (!sd_event_run(events, sleepTime.count()))
        {
            count++;
        }
    }
    EXPECT_EQ(false, timer.isExpired());

    // 2 because of one more count that happens prior to exiting
    EXPECT_EQ(2, count);
}

/** @brief Makes sure that timer value is changed in between
 *  and that the new timer expires
 */
TEST_F(TimerTest, updateTimerAndExpectExpire)
{
    using namespace std::chrono;

    auto time = duration_cast<microseconds>(seconds(2));
    EXPECT_GE(timer.start(time), 0);

    // Now sleep for a second and then set the new timeout value
    sleep(1);

    // New timeout is 3 seconds from THIS point.
    time = duration_cast<microseconds>(seconds(3));
    EXPECT_GE(timer.start(time), 0);

    // Wait 3 seconds and see that timer is expired
    int count = 0;
    while (count < 3 && !timer.isExpired())
    {
        // Returns -0- on timeout
        auto sleepTime = duration_cast<microseconds>(seconds(1));
        if (!sd_event_run(events, sleepTime.count()))
        {
            count++;
        }
    }
    EXPECT_EQ(true, timer.isExpired());
    EXPECT_EQ(2, count);
}

/** @brief Makes sure that timer value is changed in between
 *  and turn off and make sure that timer does not expire
 */
TEST_F(TimerTest, updateTimerAndNeverExpire)
{
    using namespace std::chrono;

    auto time = duration_cast<microseconds>(seconds(2));
    EXPECT_GE(timer.start(time), 0);

    // Now sleep for a second and then set the new timeout value
    sleep(1);

    // New timeout is 2 seconds from THIS point.
    time = duration_cast<microseconds>(seconds(2));
    EXPECT_GE(timer.start(time), 0);

    // Now turn off the timer post a 1 second sleep
    sleep(1);
    EXPECT_GE(timer.stop(), 0);

    // Wait 2 seconds and see that timer is expired
    int count = 0;
    while (count < 2)
    {
        // Returns -0- on timeout
        auto sleepTime = duration_cast<microseconds>(seconds(1));
        if (!sd_event_run(events, sleepTime.count()))
        {
            count++;
        }
    }
    EXPECT_EQ(false, timer.isExpired());

    // 2 because of one more count that happens prior to exiting
    EXPECT_EQ(2, count);
}

/** @brief Makes sure that optional callback is called */
TEST_F(TimerTestCallBack, optionalFuncCallBackDone)
{
    using namespace std::chrono;

    auto time = duration_cast<microseconds>(seconds(2));
    EXPECT_GE(timer->start(time), 0);

    // Waiting 2 seconds is enough here since we have
    // already spent some usec now
    int count = 0;
    while (count < 2 && !timer->isExpired())
    {
        // Returns -0- on timeout and positive number on dispatch
        auto sleepTime = duration_cast<microseconds>(seconds(1));
        if (!sd_event_run(events, sleepTime.count()))
        {
            count++;
        }
    }
    EXPECT_EQ(true, timer->isExpired());
    EXPECT_EQ(true, callBackDone);
    EXPECT_EQ(1, count);
}

/** @brief Makes sure that timer is not expired
 */
TEST_F(TimerTestCallBack, timerNotExpiredAfter2SecondsNoOptionalCallBack)
{
    using namespace std::chrono;

    auto time = duration_cast<microseconds>(seconds(2));
    EXPECT_GE(timer->start(time), 0);

    // Now turn off the timer post a 1 second sleep
    sleep(1);
    EXPECT_GE(timer->stop(), 0);

    // Wait 2 seconds and see that timer is not expired
    int count = 0;
    while (count < 2)
    {
        // Returns -0- on timeout
        auto sleepTime = duration_cast<microseconds>(seconds(1));
        if (!sd_event_run(events, sleepTime.count()))
        {
            count++;
        }
    }
    EXPECT_EQ(false, timer->isExpired());
    EXPECT_EQ(false, callBackDone);

    // 2 because of one more count that happens prior to exiting
    EXPECT_EQ(2, count);
}
