#include <chrono>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <memory>
#include <optional>
#include <sdeventplus/clock.hpp>
#include <sdeventplus/event.hpp>
#include <sdeventplus/test/sdevent.hpp>
#include <sdeventplus/utility/timer.hpp>
#include <stdexcept>
#include <systemd/sd-event.h>

namespace sdeventplus
{
namespace utility
{
namespace
{

constexpr ClockId testClock = ClockId::Monotonic;

using std::chrono::microseconds;
using std::chrono::milliseconds;
using testing::DoAll;
using testing::Return;
using testing::SaveArg;
using testing::SetArgPointee;
using TestTimer = Timer<testClock>;

ssize_t event_ref_times = 0;

ACTION(EventRef)
{
    event_ref_times++;
}

ACTION(EventUnref)
{
    ASSERT_LT(0, event_ref_times);
    event_ref_times--;
}

class TimerTest : public testing::Test
{
  protected:
    testing::StrictMock<test::SdEventMock> mock;
    sd_event* const expected_event = reinterpret_cast<sd_event*>(1234);
    sd_event_source* const expected_source =
        reinterpret_cast<sd_event_source*>(2345);
    sd_event_source* const expected_source2 =
        reinterpret_cast<sd_event_source*>(3456);
    const milliseconds interval{134};
    const milliseconds starting_time{10};
    const milliseconds starting_time2{30};
    sd_event_time_handler_t handler = nullptr;
    void* handler_userdata;
    std::unique_ptr<Event> event;
    std::unique_ptr<TestTimer> timer;
    std::function<void()> callback;

    void expectNow(microseconds ret)
    {
        EXPECT_CALL(mock,
                    sd_event_now(expected_event,
                                 static_cast<clockid_t>(testClock), testing::_))
            .WillOnce(DoAll(SetArgPointee<2>(ret.count()), Return(0)));
    }

    void expectSetTime(microseconds time)
    {
        EXPECT_CALL(mock,
                    sd_event_source_set_time(expected_source, time.count()))
            .WillOnce(Return(0));
    }

    void expectSetEnabled(source::Enabled enabled)
    {
        EXPECT_CALL(mock, sd_event_source_set_enabled(
                              expected_source, static_cast<int>(enabled)))
            .WillOnce(Return(0));
    }

    void expectGetEnabled(source::Enabled enabled)
    {
        EXPECT_CALL(mock,
                    sd_event_source_get_enabled(expected_source, testing::_))
            .WillOnce(
                DoAll(SetArgPointee<1>(static_cast<int>(enabled)), Return(0)));
    }

    void resetTimer()
    {
        if (timer)
        {
            expectSetEnabled(source::Enabled::Off);
            timer.reset();
        }
    }

    void expireTimer()
    {
        const milliseconds new_time(90);
        expectNow(new_time);
        expectSetTime(new_time + interval);
        EXPECT_EQ(0, handler(nullptr, 0, handler_userdata));
        EXPECT_TRUE(timer->hasExpired());
        EXPECT_EQ(interval, timer->getInterval());
    }

    void SetUp()
    {
        EXPECT_CALL(mock, sd_event_ref(expected_event))
            .WillRepeatedly(DoAll(EventRef(), Return(expected_event)));
        EXPECT_CALL(mock, sd_event_unref(expected_event))
            .WillRepeatedly(DoAll(EventUnref(), Return(nullptr)));
        event = std::make_unique<Event>(expected_event, &mock);
        EXPECT_CALL(mock, sd_event_source_unref(expected_source))
            .WillRepeatedly(Return(nullptr));
        EXPECT_CALL(mock,
                    sd_event_source_set_userdata(expected_source, testing::_))
            .WillRepeatedly(
                DoAll(SaveArg<1>(&handler_userdata), Return(nullptr)));

        // Having a callback proxy allows us to update the test callback
        // dynamically, without changing it inside the timer
        auto runCallback = [&](TestTimer&) {
            if (callback)
            {
                callback();
            }
        };
        expectNow(starting_time);
        EXPECT_CALL(mock, sd_event_add_time(
                              expected_event, testing::_,
                              static_cast<clockid_t>(testClock),
                              microseconds(starting_time + interval).count(),
                              1000, testing::_, nullptr))
            .WillOnce(DoAll(SetArgPointee<1>(expected_source),
                            SaveArg<5>(&handler), Return(0)));
        expectSetEnabled(source::Enabled::On);
        timer = std::make_unique<TestTimer>(*event, runCallback, interval);
        EXPECT_EQ(expected_event, timer->get_event().get());
    }

    void TearDown()
    {
        resetTimer();
        event.reset();
        EXPECT_EQ(0, event_ref_times);
    }
};

TEST_F(TimerTest, NoCallback)
{
    resetTimer();
    expectNow(starting_time);
    EXPECT_CALL(
        mock, sd_event_add_time(expected_event, testing::_,
                                static_cast<clockid_t>(testClock),
                                microseconds(starting_time + interval).count(),
                                1000, testing::_, nullptr))
        .WillOnce(DoAll(SetArgPointee<1>(expected_source), SaveArg<5>(&handler),
                        Return(0)));
    expectSetEnabled(source::Enabled::On);
    timer = std::make_unique<TestTimer>(*event, nullptr, interval);

    expectNow(starting_time);
    expectSetTime(starting_time + interval);
    EXPECT_EQ(0, handler(nullptr, 0, handler_userdata));
}

TEST_F(TimerTest, NoInterval)
{
    resetTimer();
    expectNow(starting_time);
    EXPECT_CALL(mock, sd_event_add_time(expected_event, testing::_,
                                        static_cast<clockid_t>(testClock),
                                        microseconds(starting_time).count(),
                                        1000, testing::_, nullptr))
        .WillOnce(DoAll(SetArgPointee<1>(expected_source), SaveArg<5>(&handler),
                        Return(0)));
    expectSetEnabled(source::Enabled::Off);
    timer = std::make_unique<TestTimer>(*event, nullptr);

    EXPECT_EQ(std::nullopt, timer->getInterval());
    EXPECT_THROW(timer->setEnabled(true), std::runtime_error);
}

TEST_F(TimerTest, NewTimer)
{
    EXPECT_FALSE(timer->hasExpired());
    EXPECT_EQ(interval, timer->getInterval());
}

TEST_F(TimerTest, IsEnabled)
{
    expectGetEnabled(source::Enabled::On);
    EXPECT_TRUE(timer->isEnabled());
    expectGetEnabled(source::Enabled::Off);
    EXPECT_FALSE(timer->isEnabled());
}

TEST_F(TimerTest, GetRemainingDisabled)
{
    expectGetEnabled(source::Enabled::Off);
    EXPECT_THROW(timer->getRemaining(), std::runtime_error);
}

TEST_F(TimerTest, GetRemainingNegative)
{
    milliseconds now(675), end(453);
    expectGetEnabled(source::Enabled::On);
    EXPECT_CALL(mock, sd_event_source_get_time(expected_source, testing::_))
        .WillOnce(
            DoAll(SetArgPointee<1>(microseconds(end).count()), Return(0)));
    expectNow(now);
    EXPECT_EQ(milliseconds(0), timer->getRemaining());
}

TEST_F(TimerTest, GetRemainingPositive)
{
    milliseconds now(453), end(675);
    expectGetEnabled(source::Enabled::On);
    EXPECT_CALL(mock, sd_event_source_get_time(expected_source, testing::_))
        .WillOnce(
            DoAll(SetArgPointee<1>(microseconds(end).count()), Return(0)));
    expectNow(now);
    EXPECT_EQ(end - now, timer->getRemaining());
}

TEST_F(TimerTest, SetEnabled)
{
    expectSetEnabled(source::Enabled::On);
    timer->setEnabled(true);
    EXPECT_FALSE(timer->hasExpired());
    // Value should always be passed through regardless of current state
    expectSetEnabled(source::Enabled::On);
    timer->setEnabled(true);
    EXPECT_FALSE(timer->hasExpired());

    expectSetEnabled(source::Enabled::Off);
    timer->setEnabled(false);
    EXPECT_FALSE(timer->hasExpired());
    // Value should always be passed through regardless of current state
    expectSetEnabled(source::Enabled::Off);
    timer->setEnabled(false);
    EXPECT_FALSE(timer->hasExpired());
}

TEST_F(TimerTest, SetEnabledUnsetTimer)
{
    // Force the timer to become unset
    expectSetEnabled(source::Enabled::Off);
    timer->restart(std::nullopt);

    // Setting an interval should not update the timer directly
    timer->setInterval(milliseconds(90));

    expectSetEnabled(source::Enabled::Off);
    timer->setEnabled(false);
    EXPECT_THROW(timer->setEnabled(true), std::runtime_error);
}

TEST_F(TimerTest, SetEnabledOneshot)
{
    // Timer effectively becomes oneshot if it gets initialized but has
    // the interval removed
    timer->setInterval(std::nullopt);

    expectSetEnabled(source::Enabled::Off);
    timer->setEnabled(false);
    expectSetEnabled(source::Enabled::On);
    timer->setEnabled(true);
}

TEST_F(TimerTest, SetRemaining)
{
    const milliseconds now(90), remaining(30);
    expectNow(now);
    expectSetTime(now + remaining);
    timer->setRemaining(remaining);
    EXPECT_EQ(interval, timer->getInterval());
    EXPECT_FALSE(timer->hasExpired());
}

TEST_F(TimerTest, ResetRemaining)
{
    const milliseconds now(90);
    expectNow(now);
    expectSetTime(now + interval);
    timer->resetRemaining();
    EXPECT_EQ(interval, timer->getInterval());
    EXPECT_FALSE(timer->hasExpired());
}

TEST_F(TimerTest, SetInterval)
{
    const milliseconds new_interval(40);
    timer->setInterval(new_interval);
    EXPECT_EQ(new_interval, timer->getInterval());
    EXPECT_FALSE(timer->hasExpired());
}

TEST_F(TimerTest, SetIntervalEmpty)
{
    timer->setInterval(std::nullopt);
    EXPECT_EQ(std::nullopt, timer->getInterval());
    EXPECT_FALSE(timer->hasExpired());
}

TEST_F(TimerTest, CallbackHappensLast)
{
    const milliseconds new_time(90);
    expectNow(new_time);
    expectSetTime(new_time + interval);
    callback = [&]() {
        EXPECT_TRUE(timer->hasExpired());
        expectSetEnabled(source::Enabled::On);
        timer->setEnabled(true);
        timer->clearExpired();
        timer->setInterval(std::nullopt);
    };
    EXPECT_EQ(0, handler(nullptr, 0, handler_userdata));
    EXPECT_FALSE(timer->hasExpired());
    EXPECT_EQ(std::nullopt, timer->getInterval());
    expectSetEnabled(source::Enabled::On);
    timer->setEnabled(true);
}

TEST_F(TimerTest, CallbackOneshot)
{
    // Make sure we try a one shot so we can test the callback
    // correctly
    timer->setInterval(std::nullopt);

    expectSetEnabled(source::Enabled::Off);
    callback = [&]() {
        EXPECT_TRUE(timer->hasExpired());
        EXPECT_THROW(timer->setEnabled(true), std::runtime_error);
        timer->setInterval(interval);
    };
    EXPECT_EQ(0, handler(nullptr, 0, handler_userdata));
    EXPECT_THROW(timer->setEnabled(true), std::runtime_error);
}

TEST_F(TimerTest, CallbackMove)
{
    size_t called = 0;
    callback = [&]() { ++called; };

    expectNow(starting_time2);
    EXPECT_CALL(mock,
                sd_event_source_set_userdata(expected_source2, testing::_))
        .WillOnce(Return(nullptr));
    EXPECT_CALL(mock, sd_event_add_time(expected_event, testing::_,
                                        static_cast<clockid_t>(testClock),
                                        microseconds(starting_time2).count(),
                                        1000, testing::_, nullptr))
        .WillOnce(DoAll(SetArgPointee<1>(expected_source2), Return(0)));
    EXPECT_CALL(mock, sd_event_source_unref(expected_source2))
        .WillOnce(Return(nullptr));
    EXPECT_CALL(mock,
                sd_event_source_set_enabled(
                    expected_source2, static_cast<int>(source::Enabled::Off)))
        .WillOnce(Return(0))
        .WillOnce(Return(0));
    TestTimer local_timer(*event, nullptr);

    // Move assign
    local_timer = std::move(*timer);
    timer.reset();

    // Move construct
    timer = std::make_unique<TestTimer>(std::move(local_timer));

    // handler_userdata should have been updated and the callback should work
    const milliseconds new_time(90);
    expectNow(new_time);
    expectSetTime(new_time + interval);
    EXPECT_EQ(0, handler(nullptr, 0, handler_userdata));
    EXPECT_EQ(1, called);
}

TEST_F(TimerTest, SetValuesExpiredTimer)
{
    const milliseconds new_time(90);
    expectNow(new_time);
    expectSetTime(new_time + interval);
    EXPECT_EQ(0, handler(nullptr, 0, handler_userdata));
    EXPECT_TRUE(timer->hasExpired());
    EXPECT_EQ(interval, timer->getInterval());

    // Timer should remain expired unless clearExpired() or reset()
    expectSetEnabled(source::Enabled::On);
    timer->setEnabled(true);
    EXPECT_TRUE(timer->hasExpired());
    expectNow(milliseconds(20));
    expectSetTime(milliseconds(50));
    timer->setRemaining(milliseconds(30));
    EXPECT_TRUE(timer->hasExpired());
    timer->setInterval(milliseconds(10));
    EXPECT_TRUE(timer->hasExpired());
    expectNow(milliseconds(20));
    expectSetTime(milliseconds(30));
    timer->resetRemaining();
    EXPECT_TRUE(timer->hasExpired());

    timer->clearExpired();
    EXPECT_FALSE(timer->hasExpired());
}

TEST_F(TimerTest, Restart)
{
    expireTimer();

    const milliseconds new_interval(471);
    expectNow(starting_time);
    expectSetTime(starting_time + new_interval);
    expectSetEnabled(source::Enabled::On);
    timer->restart(new_interval);
    EXPECT_FALSE(timer->hasExpired());
    EXPECT_EQ(new_interval, timer->getInterval());
    expectSetEnabled(source::Enabled::On);
    timer->setEnabled(true);
}

TEST_F(TimerTest, RestartEmpty)
{
    expireTimer();

    expectSetEnabled(source::Enabled::Off);
    timer->restart(std::nullopt);
    EXPECT_FALSE(timer->hasExpired());
    EXPECT_EQ(std::nullopt, timer->getInterval());
    EXPECT_THROW(timer->setEnabled(true), std::runtime_error);
}

TEST_F(TimerTest, RestartOnce)
{
    expireTimer();

    const milliseconds remaining(471);
    expectNow(starting_time);
    expectSetTime(starting_time + remaining);
    expectSetEnabled(source::Enabled::On);
    timer->restartOnce(remaining);
    EXPECT_FALSE(timer->hasExpired());
    EXPECT_EQ(std::nullopt, timer->getInterval());
    expectSetEnabled(source::Enabled::On);
    timer->setEnabled(true);
}

} // namespace
} // namespace utility
} // namespace sdeventplus
