/**
 * @file test_MctpUtil.cpp
 * @brief Unit tests for MctpUtil.cpp
 *
 * These tests verify the deferred state handling in MctpUtil when processing
 * MCTP endpoint discovery events. Specifically, it tests that:
 * 1. A single Add event populates the map.
 * 2. A Remove event arriving while a query is in progress correctly cancels
 *    or rolls back the operation, leaving the map empty.
 * 3. An Add -> Remove -> Add sequence in rapid succession correctly schedules
 *    a new query and leaves the map populated at the end.
 *
 * Synchronization Design:
 * To avoid impacting production code, the tests use custom D-Bus signals
 * emitted by the mock server (mock_mctpd.py) to know exactly when a query
 * starts and completes. This allows precise orchestration of events without
 * sleeps or production code hooks.
 *
 * The tests run in a single thread using `io.poll()` to match the production
 * execution model.
 */
#include "MctpUtil.hpp"
#include "Utils.hpp"

#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

#include <boost/asio/io_context.hpp>
#include <sdbusplus/asio/connection.hpp>
#include <sdbusplus/asio/object_server.hpp>
#include <sdbusplus/bus/match.hpp>

#include <array>
#include <cstdlib>
#include <iostream>
#include <memory>
#include <string>
#include <thread>
#include <vector>

#include <gtest/gtest.h>

#define xstr(s) str(s) // NOLINT
#define str(s) #s      // NOLINT

static void runCmd(const std::string& cmd)
{
    std::string finalCmd = cmd;
    const char* dbusAddr = std::getenv("DBUS_SESSION_BUS_ADDRESS");
    if (dbusAddr != nullptr)
    {
        size_t pos = finalCmd.find("busctl ");
        if (pos != std::string::npos)
        {
            finalCmd.replace(pos, 7,
                             "busctl --address=" + std::string(dbusAddr) + " ");
        }
    }
    int rc = system(finalCmd.c_str()); // NOLINT(cert-env33-c)
    ASSERT_EQ(rc, 0);
}

class MctpUtilTest : public ::testing::Test
{
  protected:
    boost::asio::io_context io;
    std::shared_ptr<sdbusplus::asio::connection> conn;
    pid_t mockPid = -1;

    void SetUp() override
    {
        io.restart();
        conn = std::make_shared<sdbusplus::asio::connection>(io);

        // Clear global map before each test
        mctpEndpointConfigMap.clear();
        std::cout << "--- Starting Python Mock ---\n";
        mockPid = fork();
        if (mockPid == 0)
        {
            // Child process
            // clang-format off
            std::string scriptPath = TEST_SRC_DIR "/mock_mctpd.py";
            execlp("python3", "python3", scriptPath.c_str(), nullptr); // NOLINT(cppcoreguidelines-pro-type-vararg)
            // clang-format on
            exit(1);
        }
        // Give mock some time to start and claim names!
        sleep(3); // NOLINT
    }

    void TearDown() override
    {
        cleanupMctpEndpointListener();
        if (mockPid > 0)
        {
            kill(mockPid, SIGTERM);
            waitpid(mockPid, nullptr, 0);
        }
    }

    static bool checkPathInMapper(const std::string& path)
    {
        std::string cmd = "busctl tree xyz.openbmc_project.ObjectMapper";
        const char* dbusAddr = std::getenv("DBUS_SESSION_BUS_ADDRESS");
        if (dbusAddr != nullptr)
        {
            cmd = "busctl --address=" + std::string(dbusAddr) +
                  " tree xyz.openbmc_project.ObjectMapper";
        }
        FILE* pipe = popen(cmd.c_str(), "r"); // NOLINT(cert-env33-c)
        if (pipe == nullptr)
        {
            return false;
        }
        std::array<char, 128> buffer{};
        std::string result;
        while (fgets(buffer.data(), buffer.size(), pipe) != nullptr)
        {
            result += buffer.data();
        }
        pclose(pipe);
        return result.find(path) != std::string::npos;
    }
};

// 1. A single Add event will trigger only one O-M query. And add the correct
// result in mctpEndpointConfigMap
TEST_F(MctpUtilTest, SingleAdd_PopulatesMap)
{
    std::string endpointPath =
        "/au/com/codeconstruct/mctp1/networks/1/endpoints/test1";
    std::string emConfigPath =
        "/xyz/openbmc_project/inventory/system/board/MockBoard/mctp_device";

    // 2.a setupMctpEndpointListener() first in the test.
    setupMctpEndpointListener(conn);

    // 2.b setup the busctl event listener to all O-M event.
    // We use a C++ match listener for all InterfacesAdded signals!
    int queryCompletedCount = 0;

    const std::string queryCompletedSpec =
        "type='signal',interface='com.example.Control',member='QueryCompleted'";
    auto queryCompletedMatch = std::make_unique<sdbusplus::bus::match_t>(
        static_cast<sdbusplus::bus_t&>(*conn), queryCompletedSpec,
        [&](sdbusplus::message_t&) { queryCompletedCount++; });

    // Wait for priming loop to complete (finding nothing)
    io.poll();
    usleep(100000); // 100ms
    io.poll();

    // Trigger Add event via D-Bus!
    std::string addCmd =
        "busctl call xyz.openbmc_project.Mctp /au/com/codeconstruct/mctp1 com.example.Control TriggerAdd ss \"" +
        endpointPath + "\" \"" + emConfigPath + "\"";
    runCmd(addCmd);

    // Wait for query to complete with a timeout (up to 5 seconds)
    for (int i = 0; i < 50; i++)
    {
        io.poll();
        usleep(100000); // NOLINT(cert-api50-c)
        if (queryCompletedCount >= 1)
        {
            break;
        }
    }

    // Wait a bit more to see if any extra signals arrive
    usleep(500000); // 500ms
    io.poll();

    EXPECT_EQ(queryCompletedCount, 1);

    // Wait a bit more for MctpUtil to process the reply!
    usleep(100000); // 100ms

    // Verify map populated
    auto it = mctpEndpointConfigMap.find(endpointPath);
    ASSERT_NE(it, mctpEndpointConfigMap.end());
    EXPECT_FALSE(it->second.empty());
}

// 2. Add -> Remove during query
TEST_F(MctpUtilTest, AddRemove_ClearsMap)
{
    std::string endpointPath =
        "/au/com/codeconstruct/mctp1/networks/1/endpoints/test2";
    std::string emConfigPath =
        "/xyz/openbmc_project/inventory/system/board/MockBoard/mctp_device";

    setupMctpEndpointListener(conn);

    bool queryStarted = false;
    int queryCompletedCount = 0;

    const std::string queryStartedSpec =
        "type='signal',interface='com.example.Control',member='QueryStarted'";
    auto queryStartedMatch = std::make_unique<sdbusplus::bus::match_t>(
        static_cast<sdbusplus::bus_t&>(*conn), queryStartedSpec,
        [&](sdbusplus::message_t&) { queryStarted = true; });

    const std::string queryCompletedSpec =
        "type='signal',interface='com.example.Control',member='QueryCompleted'";
    auto queryCompletedMatch = std::make_unique<sdbusplus::bus::match_t>(
        static_cast<sdbusplus::bus_t&>(*conn), queryCompletedSpec,
        [&](sdbusplus::message_t&) { queryCompletedCount++; });

    // Wait for priming loop to complete (finding nothing)
    io.poll();
    usleep(100000); // 100ms
    io.poll();

    // Trigger Add event
    std::string addCmd =
        "busctl call xyz.openbmc_project.Mctp /au/com/codeconstruct/mctp1 com.example.Control TriggerAdd ss \"" +
        endpointPath + "\" \"" + emConfigPath + "\"";
    runCmd(addCmd);

    // Wait for query to start
    while (!queryStarted)
    {
        io.poll();
        usleep(10000); // 10ms
    }

    // IMMEDIATELY trigger Remove event (while query is in progress!)
    std::string removeCmd =
        "busctl call xyz.openbmc_project.Mctp /au/com/codeconstruct/mctp1 com.example.Control TriggerRemove s \"" +
        endpointPath + "\"";
    runCmd(removeCmd);

    // Wait for query to complete with a timeout (up to 5 seconds)
    for (int i = 0; i < 50; i++)
    {
        io.poll();
        usleep(100000); // NOLINT(cert-api50-c)
        if (queryCompletedCount >= 1)
        {
            break;
        }
    }

    // Wait a bit more to see if any extra signals arrive
    usleep(500000); // 500ms
    io.poll();

    EXPECT_EQ(queryCompletedCount, 1);

    // Verify map is empty
    auto it = mctpEndpointConfigMap.find(endpointPath);
    EXPECT_TRUE(it == mctpEndpointConfigMap.end());
}

// 3. Add -> Remove -> Add during query
TEST_F(MctpUtilTest, AddRemoveAdd_PopulatesMap)
{
    std::string endpointPath =
        "/au/com/codeconstruct/mctp1/networks/1/endpoints/test3";
    std::string emConfigPath =
        "/xyz/openbmc_project/inventory/system/board/MockBoard/mctp_device";

    setupMctpEndpointListener(conn);

    bool queryStarted = false;
    int queryCompletedCount = 0;

    const std::string queryStartedSpec =
        "type='signal',interface='com.example.Control',member='QueryStarted'";
    auto queryStartedMatch = std::make_unique<sdbusplus::bus::match_t>(
        static_cast<sdbusplus::bus_t&>(*conn), queryStartedSpec,
        [&](sdbusplus::message_t&) { queryStarted = true; });

    const std::string queryCompletedSpec =
        "type='signal',interface='com.example.Control',member='QueryCompleted'";
    auto queryCompletedMatch = std::make_unique<sdbusplus::bus::match_t>(
        static_cast<sdbusplus::bus_t&>(*conn), queryCompletedSpec,
        [&](sdbusplus::message_t&) { queryCompletedCount++; });

    // Wait for priming loop to complete (finding nothing)
    io.poll();
    usleep(100000); // 100ms
    io.poll();

    // Trigger Add event
    std::string addCmd =
        "busctl call xyz.openbmc_project.Mctp /au/com/codeconstruct/mctp1 com.example.Control TriggerAdd ss \"" +
        endpointPath + "\" \"" + emConfigPath + "\"";
    runCmd(addCmd);

    // Wait for query to start
    while (!queryStarted)
    {
        io.poll();
        usleep(10000); // 10ms
    }

    // IMMEDIATELY trigger Remove event
    std::string removeCmd =
        "busctl call xyz.openbmc_project.Mctp /au/com/codeconstruct/mctp1 com.example.Control TriggerRemove s \"" +
        endpointPath + "\"";
    runCmd(removeCmd);

    // IMMEDIATELY trigger Add event again!
    runCmd(addCmd);

    // Wait for queries to complete with a timeout (up to 5 seconds)
    for (int i = 0; i < 70; i++)
    {
        io.poll();
        usleep(100000); // NOLINT(cert-api50-c)
        if (queryCompletedCount >= 2)
        {
            break;
        }
    }

    // Wait a bit more to see if any extra signals arrive
    usleep(500000); // 500ms
    io.poll();

    EXPECT_EQ(queryCompletedCount, 2);

    // Verify map is populated at the end
    auto it = mctpEndpointConfigMap.find(endpointPath);
    ASSERT_NE(it, mctpEndpointConfigMap.end());
    EXPECT_FALSE(it->second.empty());
}

// 4. Race between priming query and new event
TEST_F(MctpUtilTest, PrimeQueryRace_TriggersDeferredQuery)
{
    std::string endpointPath =
        "/au/com/codeconstruct/mctp1/networks/1/endpoints/test4";
    std::string emConfigPath =
        "/xyz/openbmc_project/inventory/system/board/MockBoard/mctp_device";

    // Pre-populate association by triggering it BEFORE listener starts!
    auto m = conn->new_method_call("xyz.openbmc_project.Mctp",
                                   "/au/com/codeconstruct/mctp1",
                                   "com.example.Control", "TriggerAdd");
    m.append(endpointPath, emConfigPath);
    conn->call(m);

    // Wait for mapperx to see it
    bool found = false;
    for (int i = 0; i < 300; i++)
    {
        if (checkPathInMapper(endpointPath + "/configured_by"))
        {
            found = true;
            break;
        }
        usleep(100000); // 100ms
    }
    ASSERT_TRUE(found);

    // Now setup listener (this starts priming!)
    setupMctpEndpointListener(conn);

    bool queryStarted = false;
    int queryCompletedCount = 0;

    const std::string queryStartedSpec =
        "type='signal',interface='com.example.Control',member='QueryStarted'";
    auto queryStartedMatch = std::make_unique<sdbusplus::bus::match_t>(
        static_cast<sdbusplus::bus_t&>(*conn), queryStartedSpec,
        [&](sdbusplus::message_t&) {
        std::cout << "[TEST] QueryStarted received\n";
        queryStarted = true;
    });

    const std::string queryCompletedSpec =
        "type='signal',interface='com.example.Control',member='QueryCompleted'";
    auto queryCompletedMatch = std::make_unique<sdbusplus::bus::match_t>(
        static_cast<sdbusplus::bus_t&>(*conn), queryCompletedSpec,
        [&](sdbusplus::message_t&) {
        std::cout << "[TEST] QueryCompleted received\n";
        queryCompletedCount++;
    });

    // Wait for query to start (triggered by priming!)
    while (!queryStarted)
    {
        io.poll();
        usleep(10000); // 10ms
    }

    std::string endpointPath5 =
        "/au/com/codeconstruct/mctp1/networks/1/endpoints/test5";
    std::cout << "[DEBUG] Triggering Add for test5 (racing!)\n";
    // Trigger Add event for a DIFFERENT endpoint while priming query is in
    // progress!
    conn->async_method_call(
        [](const boost::system::error_code& ec, const std::string&) {
        if (ec)
        {
            std::cout << "[TEST] TriggerAdd failed: " << ec.message() << "\n";
        }
    }, "xyz.openbmc_project.Mctp", "/au/com/codeconstruct/mctp1",
        "com.example.Control", "TriggerAdd", endpointPath5, emConfigPath);

    // Wait for queries to complete (we expect 2!)
    for (int i = 0; i < 100; i++)
    {
        while (io.poll() > 0)
        {}              // Drain all ready handlers!
        usleep(100000); // 100ms
        if (queryCompletedCount >= 2)
        {
            break;
        }
    }

    // Wait a bit more to see if any extra signals arrive
    usleep(500000); // 500ms
    io.poll();

    EXPECT_EQ(queryCompletedCount, 2);

    // Verify map populated for both endpoints!
    EXPECT_EQ(mctpEndpointConfigMap.size(), 2);

    auto it4 = mctpEndpointConfigMap.find(endpointPath);
    ASSERT_NE(it4, mctpEndpointConfigMap.end());
    EXPECT_FALSE(it4->second.empty());

    auto it5 = mctpEndpointConfigMap.find(endpointPath5);
    ASSERT_NE(it5, mctpEndpointConfigMap.end());
    EXPECT_FALSE(it5->second.empty());
}

// 5. During Priming, Remove on the single endpoint
TEST_F(MctpUtilTest, PrimeQueryRace_RemovePostponed)
{
    std::string endpointPath =
        "/au/com/codeconstruct/mctp1/networks/1/endpoints/test5";
    std::string emConfigPath =
        "/xyz/openbmc_project/inventory/system/board/MockBoard/mctp_device";

    // Pre-populate association by triggering it BEFORE listener starts!
    auto m = conn->new_method_call("xyz.openbmc_project.Mctp",
                                   "/au/com/codeconstruct/mctp1",
                                   "com.example.Control", "TriggerAdd");
    m.append(endpointPath, emConfigPath);
    conn->call(m);

    // Wait for mapperx to see it
    bool found = false;
    for (int i = 0; i < 300; i++)
    {
        if (checkPathInMapper(endpointPath + "/configured_by"))
        {
            found = true;
            break;
        }
        usleep(100000); // 100ms
    }
    ASSERT_TRUE(found);

    // Now setup listener (this starts priming!)
    setupMctpEndpointListener(conn);

    bool queryStarted = false;
    int queryCompletedCount = 0;

    const std::string queryStartedSpec =
        "type='signal',interface='com.example.Control',member='QueryStarted'";
    auto queryStartedMatch = std::make_unique<sdbusplus::bus::match_t>(
        static_cast<sdbusplus::bus_t&>(*conn), queryStartedSpec,
        [&](sdbusplus::message_t&) {
        std::cout << "[TEST] QueryStarted received\n";
        queryStarted = true;
    });

    const std::string queryCompletedSpec =
        "type='signal',interface='com.example.Control',member='QueryCompleted'";
    auto queryCompletedMatch = std::make_unique<sdbusplus::bus::match_t>(
        static_cast<sdbusplus::bus_t&>(*conn), queryCompletedSpec,
        [&](sdbusplus::message_t&) {
        std::cout << "[TEST] QueryCompleted received\n";
        queryCompletedCount++;
    });

    // Wait for query to start (triggered by priming!)
    while (!queryStarted)
    {
        io.poll();
        usleep(10000); // 10ms
    }

    std::cout << "[DEBUG] Triggering Remove (racing!)\n";
    // Trigger Remove event while priming query is in progress!
    conn->async_method_call(
        [](const boost::system::error_code& ec, const std::string&) {
        if (ec)
        {
            std::cout << "[TEST] TriggerRemove failed: " << ec.message()
                      << "\n";
        }
    }, "xyz.openbmc_project.Mctp", "/au/com/codeconstruct/mctp1",
        "com.example.Control", "TriggerRemove", endpointPath);

    // Wait for queries to complete (we expect 1!)
    for (int i = 0; i < 100; i++)
    {
        while (io.poll() > 0)
        {}              // Drain all ready handlers!
        usleep(100000); // 100ms
        if (queryCompletedCount >= 1)
        {
            break;
        }
    }

    EXPECT_EQ(queryCompletedCount, 1);

    // Verify map is EMPTY (because it was removed!)
    EXPECT_EQ(mctpEndpointConfigMap.size(), 0);

    auto it = mctpEndpointConfigMap.find(endpointPath);
    EXPECT_EQ(it, mctpEndpointConfigMap.end());
}

// 6. During Priming, Remove -> Add on the single endpoint
TEST_F(MctpUtilTest, PrimeQueryRace_RemoveAddPostponed)
{
    std::string endpointPath =
        "/au/com/codeconstruct/mctp1/networks/1/endpoints/test6";
    std::string emConfigPath =
        "/xyz/openbmc_project/inventory/system/board/MockBoard/mctp_device";

    // Pre-populate association by triggering it BEFORE listener starts!
    auto m = conn->new_method_call("xyz.openbmc_project.Mctp",
                                   "/au/com/codeconstruct/mctp1",
                                   "com.example.Control", "TriggerAdd");
    m.append(endpointPath, emConfigPath);
    conn->call(m);

    // Wait for mapperx to see it
    bool found = false;
    for (int i = 0; i < 300; i++)
    {
        if (checkPathInMapper(endpointPath + "/configured_by"))
        {
            found = true;
            break;
        }
        usleep(100000); // 100ms
    }
    ASSERT_TRUE(found);

    // Now setup listener (this starts priming!)
    setupMctpEndpointListener(conn);

    bool queryStarted = false;
    int queryCompletedCount = 0;

    const std::string queryStartedSpec =
        "type='signal',interface='com.example.Control',member='QueryStarted'";
    auto queryStartedMatch = std::make_unique<sdbusplus::bus::match_t>(
        static_cast<sdbusplus::bus_t&>(*conn), queryStartedSpec,
        [&](sdbusplus::message_t&) {
        std::cout << "[TEST] QueryStarted received\n";
        queryStarted = true;
    });

    const std::string queryCompletedSpec =
        "type='signal',interface='com.example.Control',member='QueryCompleted'";
    auto queryCompletedMatch = std::make_unique<sdbusplus::bus::match_t>(
        static_cast<sdbusplus::bus_t&>(*conn), queryCompletedSpec,
        [&](sdbusplus::message_t&) {
        std::cout << "[TEST] QueryCompleted received\n";
        queryCompletedCount++;
    });

    // Wait for query to start (triggered by priming!)
    while (!queryStarted)
    {
        io.poll();
        usleep(10000); // 10ms
    }

    std::cout << "[DEBUG] Triggering Remove (racing!)\n";
    // Trigger Remove event!
    conn->async_method_call(
        [](const boost::system::error_code& ec, const std::string&) {
        if (ec)
        {
            std::cout << "[TEST] TriggerRemove failed: " << ec.message()
                      << "\n";
        }
    }, "xyz.openbmc_project.Mctp", "/au/com/codeconstruct/mctp1",
        "com.example.Control", "TriggerRemove", endpointPath);

    std::cout << "[DEBUG] Triggering Add again (racing!)\n";
    // Trigger Add event AGAIN!
    conn->async_method_call(
        [](const boost::system::error_code& ec, const std::string&) {
        if (ec)
        {
            std::cout << "[TEST] TriggerAdd failed: " << ec.message() << "\n";
        }
    }, "xyz.openbmc_project.Mctp", "/au/com/codeconstruct/mctp1",
        "com.example.Control", "TriggerAdd", endpointPath, emConfigPath);

    // Wait for queries to complete (we expect 2!)
    for (int i = 0; i < 100; i++)
    {
        while (io.poll() > 0)
        {}              // Drain all ready handlers!
        usleep(100000); // 100ms
        if (queryCompletedCount >= 2)
        {
            break;
        }
    }

    EXPECT_EQ(queryCompletedCount, 2);

    // Verify map populated
    EXPECT_EQ(mctpEndpointConfigMap.size(), 1);

    auto it = mctpEndpointConfigMap.find(endpointPath);
    ASSERT_NE(it, mctpEndpointConfigMap.end());
    EXPECT_FALSE(it->second.empty());
}

// 7. Add delay for a single ep Add to Add event. i.e. Add -> Remove -> Add
// (this add should be cooled down).
TEST_F(MctpUtilTest, Cooldown_AddRemoveAdd_IsCooledDown)
{
    std::string endpointPath =
        "/au/com/codeconstruct/mctp1/networks/1/endpoints/test7";
    std::string emConfigPath =
        "/xyz/openbmc_project/inventory/system/board/MockBoard/mctp_device";

    setupMctpEndpointListener(conn);

    bool queryStarted = false;
    int queryCompletedCount = 0;

    const std::string queryStartedSpec =
        "type='signal',interface='com.example.Control',member='QueryStarted'";
    auto queryStartedMatch = std::make_unique<sdbusplus::bus::match_t>(
        static_cast<sdbusplus::bus_t&>(*conn), queryStartedSpec,
        [&](sdbusplus::message_t&) {
        std::cout << "[TEST] QueryStarted received\n";
        queryStarted = true;
    });

    const std::string queryCompletedSpec =
        "type='signal',interface='com.example.Control',member='QueryCompleted'";
    auto queryCompletedMatch = std::make_unique<sdbusplus::bus::match_t>(
        static_cast<sdbusplus::bus_t&>(*conn), queryCompletedSpec,
        [&](sdbusplus::message_t&) {
        std::cout << "[TEST] QueryCompleted received\n";
        queryCompletedCount++;
    });

    // Trigger FIRST Add!
    conn->async_method_call(
        [](const boost::system::error_code& ec, const std::string&) {
        if (ec)
        {
            std::cout << "[TEST] TriggerAdd failed: " << ec.message() << "\n";
        }
    }, "xyz.openbmc_project.Mctp", "/au/com/codeconstruct/mctp1",
        "com.example.Control", "TriggerAdd", endpointPath, emConfigPath);

    // Wait for FIRST query to complete!
    for (int i = 0; i < 50; i++)
    {
        while (io.poll() > 0)
        {}              // Drain all ready handlers!
        usleep(100000); // 100ms
        if (queryCompletedCount >= 1)
        {
            break;
        }
    }
    ASSERT_EQ(queryCompletedCount, 1);

    std::cout << "[DEBUG] Triggering Remove and Add (racing!)\n";
    // Trigger Remove!
    conn->async_method_call(
        [](const boost::system::error_code& ec, const std::string&) {
        if (ec)
        {
            std::cout << "[TEST] TriggerRemove failed: " << ec.message()
                      << "\n";
        }
    }, "xyz.openbmc_project.Mctp", "/au/com/codeconstruct/mctp1",
        "com.example.Control", "TriggerRemove", endpointPath);

    // Trigger SECOND Add! (Immediately after!).
    conn->async_method_call(
        [](const boost::system::error_code& ec, const std::string&) {
        if (ec)
        {
            std::cout << "[TEST] TriggerAdd failed: " << ec.message() << "\n";
        }
    }, "xyz.openbmc_project.Mctp", "/au/com/codeconstruct/mctp1",
        "com.example.Control", "TriggerAdd", endpointPath, emConfigPath);

    // Wait for SECOND query to complete!
    // We expect it to be DELAYED by 5 seconds!
    auto startTime = std::chrono::steady_clock::now();
    for (int i = 0; i < 100; i++)
    {
        while (io.poll() > 0)
        {}              // Drain all ready handlers!
        usleep(100000); // 100ms
        if (queryCompletedCount >= 2)
        {
            break;
        }
    }
    auto endTime = std::chrono::steady_clock::now();
    auto duration =
        std::chrono::duration_cast<std::chrono::seconds>(endTime - startTime)
            .count();

    EXPECT_EQ(queryCompletedCount, 2);
    EXPECT_GE(duration, 4); // Expect at least 4-5 seconds delay!

    // Verify map populated
    auto it = mctpEndpointConfigMap.find(endpointPath);
    ASSERT_NE(it, mctpEndpointConfigMap.end());
}

// 8. Priming scan does block its immediate following Add. i.e. Priming ->
// Remove -> Add (not cooldown)
TEST_F(MctpUtilTest, Cooldown_PrimingRemoveAdd_IsNormalized)
{
    std::string endpointPath =
        "/au/com/codeconstruct/mctp1/networks/1/endpoints/test8";
    std::string emConfigPath =
        "/xyz/openbmc_project/inventory/system/board/MockBoard/mctp_device";

    // Pre-populate association by triggering it BEFORE listener starts!
    auto m = conn->new_method_call("xyz.openbmc_project.Mctp",
                                   "/au/com/codeconstruct/mctp1",
                                   "com.example.Control", "TriggerAdd");
    m.append(endpointPath, emConfigPath);
    conn->call(m);

    // Wait for mapperx to see it
    bool found = false;
    for (int i = 0; i < 300; i++)
    {
        if (checkPathInMapper(endpointPath + "/configured_by"))
        {
            found = true;
            break;
        }
        usleep(100000); // 100ms
    }
    ASSERT_TRUE(found);

    // Now setup listener (this starts priming!)
    setupMctpEndpointListener(conn);

    bool queryStarted = false;
    int queryCompletedCount = 0;

    const std::string queryStartedSpec =
        "type='signal',interface='com.example.Control',member='QueryStarted'";
    auto queryStartedMatch = std::make_unique<sdbusplus::bus::match_t>(
        static_cast<sdbusplus::bus_t&>(*conn), queryStartedSpec,
        [&](sdbusplus::message_t&) {
        std::cout << "[TEST] QueryStarted received\n";
        queryStarted = true;
    });

    const std::string queryCompletedSpec =
        "type='signal',interface='com.example.Control',member='QueryCompleted'";
    auto queryCompletedMatch = std::make_unique<sdbusplus::bus::match_t>(
        static_cast<sdbusplus::bus_t&>(*conn), queryCompletedSpec,
        [&](sdbusplus::message_t&) {
        std::cout << "[TEST] QueryCompleted received\n";
        queryCompletedCount++;
    });

    // Wait for query to start (triggered by priming!)
    while (!queryStarted)
    {
        io.poll();
        usleep(10000); // 10ms
    }

    std::cout << "[DEBUG] Triggering Remove and Add (racing with priming!)\n";
    // Trigger Remove event!
    conn->async_method_call(
        [](const boost::system::error_code& ec, const std::string&) {
        if (ec)
        {
            std::cout << "[TEST] TriggerRemove failed: " << ec.message()
                      << "\n";
        }
    }, "xyz.openbmc_project.Mctp", "/au/com/codeconstruct/mctp1",
        "com.example.Control", "TriggerRemove", endpointPath);

    // Trigger Add event!
    conn->async_method_call(
        [](const boost::system::error_code& ec, const std::string&) {
        if (ec)
        {
            std::cout << "[TEST] TriggerAdd failed: " << ec.message() << "\n";
        }
    }, "xyz.openbmc_project.Mctp", "/au/com/codeconstruct/mctp1",
        "com.example.Control", "TriggerAdd", endpointPath, emConfigPath);

    // Wait for queries to complete!
    auto startTime = std::chrono::steady_clock::now();
    for (int i = 0; i < 100; i++)
    {
        while (io.poll() > 0)
        {}              // Drain all ready handlers!
        usleep(100000); // 100ms
        if (queryCompletedCount >= 2)
        {
            break;
        }
    }
    auto endTime = std::chrono::steady_clock::now();
    auto duration =
        std::chrono::duration_cast<std::chrono::seconds>(endTime - startTime)
            .count();

    EXPECT_EQ(queryCompletedCount, 2);
    EXPECT_LT(duration,
              8); // Expect it to complete without additional 5s cooldown!

    // Verify map populated
    auto it = mctpEndpointConfigMap.find(endpointPath);
    ASSERT_NE(it, mctpEndpointConfigMap.end());
}

// 9. Remove has no cooldown (i.e. Remove -> Add -> Remove (no cooldown).
TEST_F(MctpUtilTest, Cooldown_RemoveAddRemove_NoCooldown)
{
    std::string endpointPath =
        "/au/com/codeconstruct/mctp1/networks/1/endpoints/test9";
    std::string emConfigPath =
        "/xyz/openbmc_project/inventory/system/board/MockBoard/mctp_device";

    setupMctpEndpointListener(conn);

    bool queryStarted = false;
    int queryCompletedCount = 0;

    const std::string queryStartedSpec =
        "type='signal',interface='com.example.Control',member='QueryStarted'";
    auto queryStartedMatch = std::make_unique<sdbusplus::bus::match_t>(
        static_cast<sdbusplus::bus_t&>(*conn), queryStartedSpec,
        [&](sdbusplus::message_t&) {
        std::cout << "[TEST] QueryStarted received\n";
        queryStarted = true;
    });

    const std::string queryCompletedSpec =
        "type='signal',interface='com.example.Control',member='QueryCompleted'";
    auto queryCompletedMatch = std::make_unique<sdbusplus::bus::match_t>(
        static_cast<sdbusplus::bus_t&>(*conn), queryCompletedSpec,
        [&](sdbusplus::message_t&) {
        std::cout << "[TEST] QueryCompleted received\n";
        queryCompletedCount++;
    });

    // Trigger FIRST Add!
    conn->async_method_call(
        [](const boost::system::error_code& ec, const std::string&) {
        if (ec)
        {
            std::cout << "[TEST] TriggerAdd failed: " << ec.message() << "\n";
        }
    }, "xyz.openbmc_project.Mctp", "/au/com/codeconstruct/mctp1",
        "com.example.Control", "TriggerAdd", endpointPath, emConfigPath);

    // Wait for FIRST query to complete!
    for (int i = 0; i < 50; i++)
    {
        while (io.poll() > 0)
        {}              // Drain all ready handlers!
        usleep(100000); // 100ms
        if (queryCompletedCount >= 1)
        {
            break;
        }
    }
    ASSERT_EQ(queryCompletedCount, 1);

    std::cout << "[DEBUG] Triggering Remove -> Add -> Remove\n";
    // Trigger Remove!
    conn->async_method_call(
        [](const boost::system::error_code& ec, const std::string&) {
        if (ec)
        {
            std::cout << "[TEST] TriggerRemove failed: " << ec.message()
                      << "\n";
        }
    }, "xyz.openbmc_project.Mctp", "/au/com/codeconstruct/mctp1",
        "com.example.Control", "TriggerRemove", endpointPath);

    // Trigger Add!
    conn->async_method_call(
        [](const boost::system::error_code& ec, const std::string&) {
        if (ec)
        {
            std::cout << "[TEST] TriggerAdd failed: " << ec.message() << "\n";
        }
    }, "xyz.openbmc_project.Mctp", "/au/com/codeconstruct/mctp1",
        "com.example.Control", "TriggerAdd", endpointPath, emConfigPath);

    // Trigger Remove!
    conn->async_method_call(
        [](const boost::system::error_code& ec, const std::string&) {
        if (ec)
        {
            std::cout << "[TEST] TriggerRemove failed: " << ec.message()
                      << "\n";
        }
    }, "xyz.openbmc_project.Mctp", "/au/com/codeconstruct/mctp1",
        "com.example.Control", "TriggerRemove", endpointPath);

    // Wait for queries to complete!
    for (int i = 0; i < 100; i++)
    {
        while (io.poll() > 0)
        {}              // Drain all ready handlers!
        usleep(100000); // 100ms
        if (queryCompletedCount >= 2)
        {
            break;
        }
    }

    EXPECT_EQ(queryCompletedCount, 2);

    // Verify map is EMPTY!
    auto it = mctpEndpointConfigMap.find(endpointPath);
    EXPECT_EQ(it, mctpEndpointConfigMap.end());
}

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