#include "NVMeCache.hpp"

#include <valgrind/valgrind.h>

#include <boost/asio.hpp>
#include <boost/asio/spawn.hpp>

#include <gmock/gmock.h>
#include <gtest/gtest.h>

const int valgrindTimeScaler = []() {
    return (RUNNING_ON_VALGRIND != 0U) ? 10 : 1;
}();

class TestNVMeCache : public testing::Test
{
  public:
    boost::asio::io_context io;
    std::shared_ptr<Scheduler<std::chrono::steady_clock>> scheduler;

    TestNVMeCache()
    {
        scheduler = std::make_shared<Scheduler<std::chrono::steady_clock>>(io);
    }
};

class MetricMock : public MetricBase<std::chrono::steady_clock>
{
  public:
    template <class Duration>
    MetricMock(std::shared_ptr<Scheduler<std::chrono::steady_clock>> scheduler,
               Duration interval) :
        MetricBase<std::chrono::steady_clock>(
            std::move(scheduler),
            std::chrono::duration_cast<std::chrono::steady_clock::duration>(
                interval))
    {}
    ~MetricMock() override
    {
        std::cerr << "MetricMock destroy\n";
    }

    MOCK_METHOD(
        void, readDevice,
        (std::function<void(std::error_code ec, size_t size, bool complete)> &&
         cb),
        (noexcept, override));

    MOCK_METHOD((std::string_view), getIdentifier, (),
                (const, noexcept, override));

    MOCK_METHOD(bool, isCacheValid, (), (const, noexcept, override));

    MOCK_METHOD(
        (std::tuple<std::chrono::time_point<ClockType>,
                    std::chrono::time_point<ClockType>, std::span<uint8_t>>),
        getCache, (), (const, noexcept, override));
};

/**
 * Simulate the scheduling sequence for
 * * NVMe subsystem intiation
 * * Metric Instance creation (after subsystem init)
 * * Refresh/PartialRefresh
 * The scheduling process should comply to the flowchart:
 *      go/nvme-mi-cache-time-scheduling#heading=h.iolas4v1li7i
 */
TEST_F(TestNVMeCache, SechuduleSequence)
{
    // blocks for partial refresh
    static constexpr unsigned refreshStep = 4;

    boost::asio::spawn(io, [this](boost::asio::yield_context yield) {
        /* Test: metric creation within system init procedure */
        // metric 1 with 200 ms refresh rate
        auto mtx = std::make_shared<MetricMock>(this->scheduler,
                                                std::chrono::milliseconds(200) *
                                                    valgrindTimeScaler);
        ON_CALL(*mtx, readDevice)
            .WillByDefault(
                [this](std::function<void(std::error_code ec, size_t size,
                                          bool complete)>&& cb) {
            boost::asio::spawn(io,
                               [this, cb](boost::asio::yield_context yield) {
                static unsigned i = 0;
                static std::chrono::steady_clock::time_point prev{
                    std::chrono::steady_clock::time_point::min()};
                std::chrono::steady_clock::time_point current =
                    std::chrono::steady_clock::now();
                if (prev != std::chrono::steady_clock::time_point::min())
                {
                    // the refresh rate should be faster than the deginated
                    // internal + device reading delay + some buffer.
                    EXPECT_LE(current - prev,
                              std::chrono::duration_cast<
                                  std::chrono::steady_clock::duration>(
                                  std::chrono::milliseconds(
                                      static_cast<unsigned>((200 + 10) * 1.1)) *
                                  valgrindTimeScaler));
                }
                prev = current;

                // similate a device delay
                boost::asio::steady_timer timer(this->io);
                timer.expires_after(std::chrono::milliseconds(10) *
                                    valgrindTimeScaler);
                timer.async_wait(yield);

                bool complete = (++i % refreshStep) == 0U;
                cb({}, 409, complete);
            });
        });

        // the cache data fetch should not be happening until subsystem
        // initiation complete
        EXPECT_CALL(*mtx, readDevice).Times(0);

        // force refresh for metric initialization
        mtx->refresh([mtx](std::error_code ec) {
            if (ec)
            {
                std::cerr << "refresh cb1: error returned\n";
                return;
            }
            // the backgound refresh should continue
            EXPECT_CALL(*mtx, readDevice).Times(::testing::AtLeast(1));
        });

        // simulate a subsystem initiate delay
        boost::asio::spawn(io, [this](boost::asio::yield_context yield) {
            boost::asio::steady_timer timer(this->io);
            timer.expires_after(std::chrono::milliseconds(200) *
                                valgrindTimeScaler);
            timer.async_wait(yield);
        });

        /* subsystem initiation done */

        // should fetch data for 4 times for metric 1
        EXPECT_CALL(*mtx, readDevice).Times(refreshStep);
        this->scheduler->start();
        this->scheduler->dequeue();

        /* Test: metric created after system initiation */
        boost::asio::steady_timer timer(this->io);
        timer.expires_after(std::chrono::milliseconds(100) *
                            valgrindTimeScaler);
        timer.async_wait(yield);

        auto mtx2 = std::make_shared<MetricMock>(
            this->scheduler,
            std::chrono::milliseconds(300) * valgrindTimeScaler);
        ON_CALL(*mtx2, readDevice)
            .WillByDefault(
                [this](std::function<void(std::error_code ec, size_t size,
                                          bool complete)>&& cb) {
            boost::asio::spawn(io,
                               [this, cb](boost::asio::yield_context yield) {
                static unsigned i = 0;
                // similate a device delay
                boost::asio::steady_timer timer(this->io);
                timer.expires_after(std::chrono::milliseconds(10) *
                                    valgrindTimeScaler);
                timer.async_wait(yield);

                bool complete = (++i % refreshStep) == 0U;
                cb({}, 409, complete);
            });
        });

        // the force refresh should start immediately
        EXPECT_CALL(*mtx2, readDevice).Times(refreshStep);
        // force refresh for metric initialization
        mtx2->refresh([mtx2](std::error_code ec) {
            if (ec)
            {
                std::cerr << "refresh cb2: error returned\n";
                return;
            }
            // the backgound refresh should continue
            EXPECT_CALL(*mtx2, readDevice).Times(::testing::AtLeast(1));
        });

        /* Test: refresh and partial refresh */
        timer.expires_after(std::chrono::seconds(1) * valgrindTimeScaler);
        timer.async_wait(yield);

        mtx2->refresh([mtx2](std::error_code ec) {
            if (ec)
            {
                std::cerr << "refresh cb3: error returned\n";
                return;
            }
            // the backgound refresh should continue
            EXPECT_CALL(*mtx2, readDevice).Times(::testing::AtLeast(1));
        });
        mtx2->partialRefresh([mtx2](std::error_code ec) {
            if (ec)
            {
                std::cerr << "partial refresh cb1: error returned\n";
                return;
            }
            // refresh should continue until completion
            EXPECT_CALL(*mtx2, readDevice)
                .Times(::testing::AtMost(refreshStep - 1));
        });
        // read device only once for partial refresh
        EXPECT_CALL(*mtx2, readDevice).Times(1);

        /* Test: Metric deletion */
        timer.expires_after(std::chrono::seconds(1) * valgrindTimeScaler);
        timer.async_wait(yield);
        bool exitWithCancel = false;
        mtx2->refresh([&exitWithCancel](std::error_code ec) {
            if (ec)
            {
                exitWithCancel = true;
                return;
            }
        });
        // slightly wait to push the task into queue
        timer.expires_after(std::chrono::milliseconds(1) * valgrindTimeScaler);
        timer.async_wait(yield);
        // destroy the metric
        mtx2.reset();
        // slightly wait until the async destroy complete
        timer.expires_after(std::chrono::milliseconds(1) * valgrindTimeScaler);
        timer.async_wait(yield);
        //
        EXPECT_EQ(exitWithCancel, true);

        // keep the subsystem running
        timer.expires_after(std::chrono::seconds(1) * valgrindTimeScaler);
        timer.async_wait(yield);
    });

    io.run();
}

/**
 * Simulate a cucurrency of caller for the cache refresh task.
 * Make sure the callback are issued in the expected behavior as the example:
 *
 *      go/nvme-mi-cache-time-scheduling#heading=h.xnlsabh6sfwj
 */
TEST_F(TestNVMeCache, ConcurrentInvoker)
{
    boost::asio::spawn(io, [this](boost::asio::yield_context yield) {
        /* create the schedule and metric*/
        // metric with infinity refresh rate to make sure no background refresh
        auto mtx = std::make_shared<MetricMock>(
            this->scheduler, std::chrono::steady_clock::duration::max());

        // metric parameters
        static constexpr unsigned refreshStep = 6;
        static const auto deviceDelay = std::chrono::milliseconds(10) *
                                        valgrindTimeScaler;
        static unsigned currentStep = 0;
        static std::chrono::steady_clock::time_point prevTime{
            std::chrono::steady_clock::time_point::min()};

        // default readDevice should return a very large data size to block the
        // background schduling for next partialRefresh
        ON_CALL(*mtx, readDevice)
            .WillByDefault(
                [this](std::function<void(std::error_code ec, size_t size,
                                          bool complete)>&& cb) {
            boost::asio::spawn(io,
                               [this, cb](boost::asio::yield_context yield) {
                std::chrono::steady_clock::time_point currentTime =
                    std::chrono::steady_clock::now();

                prevTime = currentTime;

                std::cerr << "step: " << currentStep << ", current time: "
                          << currentTime.time_since_epoch().count() << '\n';

                // similate a device delay
                boost::asio::steady_timer timer(this->io);
                timer.expires_after(deviceDelay);
                timer.async_wait(yield);

                std::cerr << "step: " << currentStep << '\n';
                std::cerr << "previous time: "
                          << currentTime.time_since_epoch().count() << '\n';
                bool complete = (++currentStep % refreshStep) == 0U;
                if (currentStep == refreshStep)
                {
                    currentStep = 0;
                }

                std::cerr << "complete: " << complete << '\n';
                cb({}, 4096000000, complete);
            });
        });

        // the cache data fetch should not be happening until subsystem
        // initiation complete
        EXPECT_CALL(*mtx, readDevice).Times(0);

        this->scheduler->start();
        this->scheduler->dequeue();

        // caller A
        std::cerr << "caller A\n";
        EXPECT_CALL(*mtx, readDevice).Times(1);
        mtx->partialRefresh([mtx](std::error_code ec) {
            EXPECT_FALSE(ec);
            std::cerr << "notify A\n";
            // the backgound refresh should continue
            EXPECT_CALL(*mtx, readDevice).Times(0);
        });

        boost::asio::steady_timer timer(this->io);
        timer.expires_after(deviceDelay * 2);
        timer.async_wait(yield);

        // move forward to step 1
        EXPECT_EQ(currentStep, 1);

        /* caller B to caller G */
        // check by currentStep in the future.
        EXPECT_CALL(*mtx, readDevice).Times(::testing::AtLeast(1));
        // caller B
        std::cerr << "caller B\n";
        mtx->refresh([mtx](std::error_code ec) {
            EXPECT_FALSE(ec);
            std::cerr << "notify B\n";
            EXPECT_EQ(currentStep, 0);
            // The schuduler should stop until next caller (G)
            EXPECT_CALL(*mtx, readDevice).Times(0);
        });

        // move forward to step 2
        timer.expires_after(deviceDelay + deviceDelay / 10);
        timer.async_wait(yield);
        EXPECT_EQ(currentStep, 2);

        // caller C
        std::cerr << "caller C\n";
        mtx->refresh([mtx](std::error_code ec) {
            EXPECT_FALSE(ec);
            std::cerr << "notify C\n";
            EXPECT_EQ(currentStep, 0);
            // The schuduler should stop until next caller (G)
            EXPECT_CALL(*mtx, readDevice).Times(0);
        });

        // metric should continue to step 3
        timer.expires_after(deviceDelay);
        timer.async_wait(yield);
        EXPECT_EQ(currentStep, 3);

        // caller D
        std::cerr << "caller D\n";
        mtx->partialRefresh([mtx](std::error_code ec) {
            EXPECT_FALSE(ec);
            std::cerr << "notify D\n";
            EXPECT_EQ(currentStep, 4);
        });

        // caller E
        std::cerr << "caller E\n";
        mtx->partialRefresh([mtx](std::error_code ec) {
            EXPECT_FALSE(ec);
            std::cerr << "notify E\n";
            EXPECT_EQ(currentStep, 4);
        });

        // move forward to next cycle (step 0)
        timer.expires_after(deviceDelay * 10);
        timer.async_wait(yield);
        EXPECT_EQ(currentStep, 0);

        // caller G
        std::cerr << "caller G\n";
        EXPECT_CALL(*mtx, readDevice).Times(1);
        mtx->partialRefresh([mtx](std::error_code ec) {
            EXPECT_FALSE(ec);
            std::cerr << "notify G\n";
            // no more data fetch until next caller
            EXPECT_CALL(*mtx, readDevice).Times(0);
        });

        // move forward to setp 1
        timer.expires_after(deviceDelay * 2);
        timer.async_wait(yield);

        EXPECT_EQ(currentStep, 1);

        // caller H
        std::cerr << "caller H\n";
        EXPECT_CALL(*mtx, readDevice).Times(::testing::AnyNumber());
        mtx->partialRefresh([mtx](std::error_code ec) {
            EXPECT_FALSE(ec);
            std::cerr << "notify H\n";
            EXPECT_EQ(currentStep, 2);
        });

        // move forward slightly
        timer.expires_after(deviceDelay / 4);
        timer.async_wait(yield);

        // caller I
        std::cerr << "caller I\n";
        bool completeI = false;
        mtx->refresh([&completeI](std::error_code ec) {
            // should be cancelled
            EXPECT_TRUE(ec);
            std::cerr << "notify I\n";
            // either step 3 or 4 depends on if the async readDevice is
            // compeleted or not
            EXPECT_GE(currentStep, 3);
            EXPECT_LE(currentStep, 4);

            completeI = true;
        });

        // move forward to step 3
        timer.expires_after(deviceDelay * 2);
        timer.async_wait(yield);

        // caller J
        std::cerr << "caller J\n";
        bool completeJ = false;
        mtx->partialRefresh([&completeJ](std::error_code ec) {
            // should be cancelled
            EXPECT_TRUE(ec);
            std::cerr << "notify J\n";
            // either step 3 or 4 depends on if the async readDevice is
            // compeleted or not
            EXPECT_GE(currentStep, 3);
            EXPECT_LE(currentStep, 4);

            completeJ = true;
        });

        // matrix Closure
        mtx.reset();

        // the notify I/J should be executed immediately after the Closure
        timer.expires_after(std::chrono::microseconds(1));
        timer.async_wait(yield);

        EXPECT_TRUE(completeI);
        EXPECT_TRUE(completeJ);

        timer.expires_after(deviceDelay * 10);
        timer.async_wait(yield);

        this->scheduler.reset();
    });

    io.run();
}

int main(int argc, char** argv)
{
    ::testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}
