#include "dbus_utility.hpp"
#include "managed_store.hpp"
#include "managed_store_types.hpp"

#include <boost/asio/io_context.hpp>

#include <memory>
#include <thread>

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

namespace managedStore
{
namespace
{

using namespace std::chrono_literals;
using testing::_;
using testing::DoAll;
using testing::InvokeArgument;
using testing::Return;

constexpr std::chrono::duration kTestShortDuration = 20ms;
constexpr std::chrono::duration kTestMediumDuration = 50ms;
constexpr std::chrono::duration kTestLongDuration = 100ms;

// Pending dbus response count used in tests.
constexpr size_t kPendingDbusResponseLow = 2;
constexpr size_t kPendingDbusResponseHigh = 10;

class MockManagedObjectStore : public ManagedObjectStore
{
  public:
    MockManagedObjectStore(const ManagedObjectStoreConfig& cfg,
                           boost::asio::io_context& io) :
        ManagedObjectStore(cfg, io)
    {}

    const std::unordered_map<std::string, ValueType>&
        getManagedObjectsFromStore() const
    {
        return this->getManagedObjects();
    }

    const ManagedStorePriorityQueue& getManagedStorePriorityQueue() const
    {
        return this->getPriorityQueue();
    }

    MOCK_METHOD(void, getManagedObjectsFromDbusService,
                (const std::string&, const sdbusplus::message::object_path&,
                 ManagedStoreCb&&),
                (override));
    MOCK_METHOD(void, getManagedPropertiesMapFromDbusService,
                (const std::string&, const sdbusplus::message::object_path&,
                 const std::string&, ManagedStoreCb&&),
                (override));
};

ValueType GenerateTestValue(
    ManagedType type = ManagedType::kManagedObject,
    std::chrono::milliseconds tfixedTestDuration = kTestShortDuration)
{
    const auto now = clockNow();
    if (type == ManagedType::kManagedPropertyMap)
    {
        return ValueType(
            dbus::utility::DBusPropertiesMap{},
            boost::system::errc::make_error_code(boost::system::errc::success),
            now, now + tfixedTestDuration);
    }
    return ValueType(
        dbus::utility::ManagedObjectType{},
        boost::system::errc::make_error_code(boost::system::errc::success), now,
        now + tfixedTestDuration);
}

TEST(ManagedStoreTest, TestPendingDbusCallsDoNotExceedThreshold)
{
    auto io = std::make_shared<boost::asio::io_context>();
    managedStore::ManagedObjectStoreConfig config(
        true /*isEnabled*/, kPendingDbusResponseLow /*pendingDbusResponsesMax*/,
        kTestShortDuration /*tfixed*/, kTestShortDuration /*tgrace*/,
        kTestLongDuration /*tLRU*/);
    auto mockManagedStore =
        std::make_shared<MockManagedObjectStore>(config, *io);
    auto testVal = GenerateTestValue();
    EXPECT_CALL(*mockManagedStore, getManagedObjectsFromDbusService(_, _, _))
        .Times(5) // 3 High priority + 2 low priority pending dbus calls allowed
        .WillOnce(
            ::testing::InvokeArgument<2>(testVal)) // High priority, upsert!
        .WillOnce(
            ::testing::InvokeArgument<2>(testVal)) // High priority, upsert!
        .WillOnce(
            ::testing::InvokeArgument<2>(testVal)) // High priority, upsert!
        .WillOnce(Return())  // No response sent to ensure pending state
        .WillOnce(Return()); // No response sent to ensure pending state
    mockManagedStore->getManagedObjects(
        "xyz", {},
        [](const boost::system::error_code&,
           const dbus::utility::ManagedObjectType&) {});
    mockManagedStore->getManagedObjects(
        "abc", {},
        [](const boost::system::error_code&,
           const dbus::utility::ManagedObjectType&) {});
    mockManagedStore->getManagedObjects(
        "efg", {},
        [](const boost::system::error_code&,
           const dbus::utility::ManagedObjectType&) {});
    io->run_for(kTestShortDuration);
    EXPECT_EQ(mockManagedStore->getStoreTracker().countPendingDbusResponses, 2);
}

TEST(ManagedStoreTest, TestHighPriorityDbusCallsNotBlocked)
{
    auto io = std::make_shared<boost::asio::io_context>();
    managedStore::ManagedObjectStoreConfig config(
        true /*isEnabled*/,
        kPendingDbusResponseLow /*pendingDbusResponsesMax*/);
    auto mockManagedStore =
        std::make_shared<MockManagedObjectStore>(config, *io);
    int executionCount = 5;
    EXPECT_CALL(*mockManagedStore, getManagedObjectsFromDbusService).Times(1);
    for (int i = 0; i < executionCount; ++i)
    {
        mockManagedStore->getManagedObjects(
            "", {},
            [](const boost::system::error_code&,
               const dbus::utility::ManagedObjectType&) {});
    }
}

TEST(ManagedStoreTest, TestGetManagedObjectCallbackInvoked)
{
    auto io = std::make_shared<boost::asio::io_context>();
    managedStore::ManagedObjectStoreConfig config(
        true /*isEnabled*/,
        kPendingDbusResponseLow /*pendingDbusResponsesMax*/);
    auto mockManagedStore =
        std::make_shared<MockManagedObjectStore>(config, *io);
    size_t callbackInvoked = 0;
    EXPECT_CALL(*mockManagedStore, getManagedObjectsFromDbusService(_, _, _))
        .WillOnce(::testing::InvokeArgument<2>(
            GenerateTestValue())); // High priority, upsert!
    mockManagedStore->getManagedObjects(
        "", {},
        [&callbackInvoked](const boost::system::error_code&,
                           const dbus::utility::ManagedObjectType&) {
        ++callbackInvoked;
        });
    EXPECT_EQ(callbackInvoked, 1);
}

TEST(ManagedStoreTest, TestManagedStoreRefreshesObjectsInStoreAfterTfixed)
{
    // Setup
    auto io = std::make_shared<boost::asio::io_context>();
    managedStore::ManagedObjectStoreConfig config(
        true /*isEnabled*/,
        kPendingDbusResponseHigh /*pendingDbusResponsesMax*/,
        kTestMediumDuration /*tfixed*/, kTestMediumDuration /*tgrace*/);
    auto mockManagedStore =
        std::make_shared<MockManagedObjectStore>(config, *io);
    const auto& objects = mockManagedStore->getManagedObjectsFromStore();

    // Configure mock to repeatedly respond to refresh requests.
    EXPECT_CALL(*mockManagedStore, getManagedObjectsFromDbusService(_, _, _))
        .WillRepeatedly(::testing::InvokeArgument<2>(GenerateTestValue(
            ManagedType::kManagedObject, kTestMediumDuration)));

    // First call for each object adds an entry in the store.
    mockManagedStore->getManagedObjects(
        "xyz", {},
        [](const boost::system::error_code&,
           const dbus::utility::ManagedObjectType&) {});
    mockManagedStore->getManagedObjects(
        "abc", {},
        [](const boost::system::error_code&,
           const dbus::utility::ManagedObjectType&) {});
    mockManagedStore->getManagedObjects(
        "efg", {},
        [](const boost::system::error_code&,
           const dbus::utility::ManagedObjectType&) {});

    // Run scheduler for time less than tfixed to make sure no refreshes
    io->run_for(kTestShortDuration);

    // No refresh until scheduled time
    for (const auto& iter : objects)
    {
        EXPECT_EQ(0, iter.second.numRefreshesDone);
    }

    // Now run the scheduler to make sure time just goes beyond tfixed and
    // refresh occurs.
    io->run_for(kTestMediumDuration);
    // Refresh occurs when time > tfixed.
    for (const auto& iter : objects)
    {
        EXPECT_GT(iter.second.numRefreshesDone, 1);
        EXPECT_EQ(1, iter.second.numTimesUsed);
    }
    auto tracker = mockManagedStore->getStoreTracker();
    EXPECT_EQ(3, tracker.countGetManagedObjectsCacheMiss);
    EXPECT_EQ(0, tracker.countGetManagedObjectsCacheHit);
    EXPECT_EQ(0, tracker.countGetManagedObjectsCacheMissMaxAge);

    // second call:
    mockManagedStore->getManagedObjects(
        "xyz", {},
        [](const boost::system::error_code&,
           const dbus::utility::ManagedObjectType&) {});
    mockManagedStore->getManagedObjects(
        "abc", {},
        [](const boost::system::error_code&,
           const dbus::utility::ManagedObjectType&) {});
    mockManagedStore->getManagedObjects(
        "efg", {},
        [](const boost::system::error_code&,
           const dbus::utility::ManagedObjectType&) {});

    // numTimesUsed is now at 2
    for (const auto& iter : mockManagedStore->getManagedObjectsFromStore())
    {
        EXPECT_EQ(2, iter.second.numTimesUsed);
        EXPECT_GT(iter.second.lastUsedAges->size(), 0);
    }
    tracker = mockManagedStore->getStoreTracker();
    EXPECT_EQ(3, tracker.countGetManagedObjectsCacheMiss);
    EXPECT_EQ(3, tracker.countGetManagedObjectsCacheHit);
    EXPECT_EQ(0, tracker.countGetManagedObjectsCacheMissMaxAge);
}

TEST(ManagedStoreTest, TestObjectsInStoreAreEvictedAfterLruThreshold)
{
    // Setup
    auto io = std::make_shared<boost::asio::io_context>();
    managedStore::ManagedObjectStoreConfig config(
        true /*isEnabled*/,
        kPendingDbusResponseHigh /*pendingDbusResponsesMax*/,
        std::chrono::milliseconds(kTestShortDuration) /*tfixed*/,
        std::chrono::milliseconds(kTestShortDuration) /*tgrace*/,
        std::chrono::milliseconds(kTestMediumDuration) /*tLRU*/);
    auto mockManagedStore =
        std::make_shared<MockManagedObjectStore>(config, *io);
    const auto& objects = mockManagedStore->getManagedObjectsFromStore();

    // Configure mock to repeatedly respond to refresh requests.
    EXPECT_CALL(*mockManagedStore, getManagedObjectsFromDbusService(_, _, _))
        .WillRepeatedly(::testing::InvokeArgument<2>(GenerateTestValue()));

    // First call for each object adds an entry in the store.
    mockManagedStore->getManagedObjects(
        "xyz", {},
        [](const boost::system::error_code&,
           const dbus::utility::ManagedObjectType&) {});

    // Run scheduler till the first refresh is due
    // At this point the object is still fresh.
    io->run_for(kTestShortDuration);

    // We expect the objects will be in store.
    EXPECT_EQ(1, objects.size());

    // Now run the scheduler to make sure time exceeds LRU threshold
    io->run_for(kTestMediumDuration);

    // We expect the object to be evicted.
    EXPECT_EQ(0, objects.size());
}

TEST(ManagedStoreTest, TestManagedStoreRefreshesOverdueObjects)
{
    auto io = std::make_shared<boost::asio::io_context>();
    managedStore::ManagedObjectStoreConfig config(
        true /*isEnabled*/, 5 /*thresholdPendingDbusResponses*/,
        kTestShortDuration /*tfixed*/, kTestShortDuration /*tgrace*/,
        kTestLongDuration /*tLRU*/);
    auto mockManagedStore =
        std::make_shared<MockManagedObjectStore>(config, *io);
    auto testVal = GenerateTestValue();
    managedStore::ManagedObjectStore::ManagedStoreCb managedStoreCb;
    EXPECT_CALL(*mockManagedStore, getManagedObjectsFromDbusService(_, _, _))
        .Times(6) // 3 cache miss + 3 refresh call
        .WillOnce(
            ::testing::InvokeArgument<2>(testVal)) // High priority, upsert!
        .WillOnce(
            ::testing::InvokeArgument<2>(testVal)) // High priority, upsert!
        .WillOnce(
            ::testing::InvokeArgument<2>(testVal)) // High priority, upsert!
        .WillOnce(Return())                        // Refresh
        .WillOnce(Return())                        // Refresh
        .WillOnce(Return());                       // Refresh
    mockManagedStore->getManagedObjects(
        "xyz", {},
        [](const boost::system::error_code&,
           const dbus::utility::ManagedObjectType&) {});
    mockManagedStore->getManagedObjects(
        "abc", {},
        [](const boost::system::error_code&,
           const dbus::utility::ManagedObjectType&) {});
    mockManagedStore->getManagedObjects(
        "efg", {},
        [](const boost::system::error_code&,
           const dbus::utility::ManagedObjectType&) {});

    // At this point the Cache is warm with 3 ManagedObjects.
    // One object from the queue which has the earliest deadline will be pop'd
    // to schedule a refresh after tfixed. So priority queue will only have 2
    // elements.
    EXPECT_EQ(2, mockManagedStore->getManagedStorePriorityQueue().size());

    // If we run io event loop now, all overdue objects should refresh and
    // priority queue should get empty.
    io->run_for(kTestShortDuration);

    // Check there are no objects in PQ
    EXPECT_EQ(0, mockManagedStore->getManagedStorePriorityQueue().size());
}

TEST(ManagedStoreTest, TestManagedStorePreventsDuplicateReadThrough)
{
    auto io = std::make_shared<boost::asio::io_context>();
    managedStore::ManagedObjectStoreConfig config(
        true /*isEnabled*/, 5 /*thresholdPendingDbusResponses*/,
        kTestShortDuration /*tfixed*/, kTestShortDuration /*tgrace*/,
        kTestLongDuration /*tLRU*/);
    auto mockManagedStore =
        std::make_shared<MockManagedObjectStore>(config, *io);
    auto testVal = GenerateTestValue();
    EXPECT_CALL(*mockManagedStore, getManagedObjectsFromDbusService(_, _, _))
        .Times(2)
        .WillRepeatedly(
            ::testing::InvokeArgument<2>(testVal)); // High priority, upsert!
    size_t callbackInvoked = 0;
    mockManagedStore->getManagedObjects(
        "abc", {},
        [&](const boost::system::error_code&,
            const dbus::utility::ManagedObjectType&) { ++callbackInvoked; });
    // 2 Similar requests back to back to create the test scenario where
    // managed store will have to block redundant request.
    mockManagedStore->getManagedObjects(
        "xyz", {},
        [&](const boost::system::error_code&,
            const dbus::utility::ManagedObjectType&) { ++callbackInvoked; });
    mockManagedStore->getManagedObjects(
        "xyz", {},
        [&](const boost::system::error_code&,
            const dbus::utility::ManagedObjectType&) { ++callbackInvoked; });

    // abc is scheduled and 1 xyz in priority queue waiting to be scheduled
    // Note, we don't expect 2 xyz in priority queue since the store does not
    // allow multiple read through requests.
    EXPECT_EQ(1, mockManagedStore->getManagedStorePriorityQueue().size());
    // Make sure the callback is invoked for duplicate xyz request.
    EXPECT_EQ(callbackInvoked, 3);
}

TEST(ManagedStoreTest, TestGetAllProperties)
{
    auto io = std::make_shared<boost::asio::io_context>();
    managedStore::ManagedObjectStoreConfig config(
        true /*isEnabled*/,
        kPendingDbusResponseLow /*thresholdPendingDbusResponses*/);
    auto mockManagedStore =
        std::make_shared<MockManagedObjectStore>(config, *io);
    size_t callbackInvoked = 0;
    EXPECT_CALL(*mockManagedStore,
                getManagedPropertiesMapFromDbusService(_, _, _, _))
        .Times(1)
        .WillRepeatedly(::testing::InvokeArgument<3>(GenerateTestValue(
            ManagedType::kManagedPropertyMap))); // High priority, upsert!
    std::shared_ptr<bmcweb::AsyncResp> asyncResp =
        std::make_shared<bmcweb::AsyncResp>();
    managedStore::ManagedObjectStoreContext context(asyncResp);
    mockManagedStore->getAllProperties(
        "ObjectPath", "Interface", "Property", context,
        [&callbackInvoked](const boost::system::error_code&,
                           const dbus::utility::DBusPropertiesMap&) {
        ++callbackInvoked;
        });
    EXPECT_EQ(callbackInvoked, 1);

    // At this point GetAllProperty should be stored and any further requests
    // should be served from store.
    mockManagedStore->getAllProperties(
        "ObjectPath", "Interface", "Property", context,
        [&callbackInvoked](const boost::system::error_code&,
                           const dbus::utility::DBusPropertiesMap&) {
        ++callbackInvoked;
        });
    EXPECT_EQ(callbackInvoked, 2);
}

TEST(ManagedStoreTest, TestManagedStoreAvoidsDuplicatePqEntries)
{
    auto io = std::make_shared<boost::asio::io_context>();
    managedStore::ManagedObjectStoreConfig config(
        true /*isEnabled*/, 1 /*thresholdPendingDbusResponses*/,
        kTestShortDuration /*tfixed*/, 0ms /*tgrace*/,
        kTestLongDuration /*tLRU*/);
    auto mockManagedStore =
        std::make_shared<MockManagedObjectStore>(config, *io);
    {
        testing::InSequence s;
        EXPECT_CALL(*mockManagedStore,
                    getManagedObjectsFromDbusService(_, _, _))
            .WillOnce(::testing::InvokeArgument<2>(GenerateTestValue()));
        EXPECT_CALL(*mockManagedStore,
                    getManagedObjectsFromDbusService(_, _, _))
            .WillOnce(::testing::InvokeArgument<2>(GenerateTestValue()));
        EXPECT_CALL(*mockManagedStore,
                    getManagedObjectsFromDbusService(_, _, _))
            .WillOnce(::testing::InvokeArgument<2>(GenerateTestValue()));
        EXPECT_CALL(*mockManagedStore,
                    getManagedObjectsFromDbusService(_, _, _))
            .WillOnce(::testing::InvokeArgument<2>(GenerateTestValue()));
        EXPECT_CALL(*mockManagedStore,
                    getManagedObjectsFromDbusService(_, _, _))
            .WillOnce(::testing::InvokeArgument<2>(GenerateTestValue()));
    }

    mockManagedStore->getManagedObjects(
        "abc", {},
        [&](const boost::system::error_code&,
            const dbus::utility::ManagedObjectType&) {});

    // Expect PQ size to be 0 since the store has only 1 entry at this point
    // which will always be scheduled for refresh.
    EXPECT_EQ(0, mockManagedStore->getManagedStorePriorityQueue().size());

    // Add another entry. This time the entry should wait in PQ to be scheduled.
    mockManagedStore->getManagedObjects(
        "xyz", {},
        [&](const boost::system::error_code&,
            const dbus::utility::ManagedObjectType&) {});
    EXPECT_EQ(1, mockManagedStore->getManagedStorePriorityQueue().size());

    // Make the entries in the PQ stale
    std::this_thread::sleep_for(kTestShortDuration);

    mockManagedStore->getManagedObjects(
        "def", {},
        [&](const boost::system::error_code&,
            const dbus::utility::ManagedObjectType&) {});

    EXPECT_EQ(2, mockManagedStore->getManagedStorePriorityQueue().size());

    // Now send a request for object that has become stale in managedStore.
    // We want to make sure pq size does not grow and the old pq entry for xyz
    // is pop'd and gets requeued after "def"
    mockManagedStore->getManagedObjects(
        "xyz", {},
        [&](const boost::system::error_code&,
            const dbus::utility::ManagedObjectType&) {});

    // Expect PQ size to sill be 2 as managed store makes sure duplicate entries
    // don't go into the priority queue.
    EXPECT_EQ(2, mockManagedStore->getManagedStorePriorityQueue().size());

    // Run io loop once to trigger scheduler to fetch new entries from pq.
    io->run_one();

    auto pq = mockManagedStore->getManagedStorePriorityQueue();

    // We want to make sure that the old pq entry for xyz is pop'd and gets
    // requeued after "def". "def" will be picked by the scheduler in that case
    // and we should see "xyz" as the top entry in pq (which in error case
    // would have been "abc")
    EXPECT_EQ("0|xyz|", pq.top().managedStoreKey.toString());
}

} // namespace
} // namespace managedStore
