/**
 * @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 "MctpReactorDevice.hpp"
#include "MctpUtil.hpp"
#include "Utils.hpp"

#include <sys/prctl.h>
#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 <csignal>
#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
            // Ask the kernel to automatically send SIGTERM to this process
            // if the parent (the test suite) dies for any reason, including a
            // segfault.
            // clang-format off
            prctl(PR_SET_PDEATHSIG, SIGTERM); // NOLINT(cppcoreguidelines-pro-type-vararg)
            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);
        }
        // Wait for mock to claim names
        bool ready = false;
        for (int i = 0; i < 50; i++)
        {
            std::string cmd =
                "busctl call org.freedesktop.DBus /org/freedesktop/DBus "
                "org.freedesktop.DBus GetNameOwner s "
                "au.com.codeconstruct.MCTP1 > /dev/null 2>&1";
            const char* dbusAddr = std::getenv("DBUS_SESSION_BUS_ADDRESS");
            if (dbusAddr != nullptr)
            {
                size_t pos = cmd.find("busctl ");
                if (pos != std::string::npos)
                {
                    cmd.replace(pos, 7,
                                "busctl --address=" + std::string(dbusAddr) +
                                    " ");
                }
            }
            int rc = system(cmd.c_str()); // NOLINT(cert-env33-c)
            if (rc != -1 && WIFEXITED(rc) && WEXITSTATUS(rc) == 0)
            {
                ready = true;
                break;
            }
            usleep(100000); // 100ms
        }

        ASSERT_TRUE(ready)
            << "Mock mctpd service au.com.codeconstruct.MCTP1 not ready!";
    }

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

        // First, process any pending D-Bus replies (like GetSubTree) while conn
        // is still externally referenced. This prevents conn from destructing
        // inside sd_bus_process if a callback drops the last reference.
        while (io.poll() > 0)
        {}

        // Now safely destroy the connection
        conn.reset();

        // Drain any cancellation handlers (e.g. async_read) queued by conn's
        // destructor
        while (io.poll() > 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, MctpMessageType::NVME_MI);

    // 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 au.com.codeconstruct.MCTP1 /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, MctpMessageType::NVME_MI);

    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 au.com.codeconstruct.MCTP1 /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 au.com.codeconstruct.MCTP1 /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, MctpMessageType::NVME_MI);

    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 au.com.codeconstruct.MCTP1 /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 au.com.codeconstruct.MCTP1 /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("au.com.codeconstruct.MCTP1",
                                   "/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, MctpMessageType::NVME_MI);

    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";
        }
    }, "au.com.codeconstruct.MCTP1", "/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("au.com.codeconstruct.MCTP1",
                                   "/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, MctpMessageType::NVME_MI);

    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";
        }
    }, "au.com.codeconstruct.MCTP1", "/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("au.com.codeconstruct.MCTP1",
                                   "/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, MctpMessageType::NVME_MI);

    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";
        }
    }, "au.com.codeconstruct.MCTP1", "/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";
        }
    }, "au.com.codeconstruct.MCTP1", "/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, MctpMessageType::NVME_MI);

    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';
        }
    }, "au.com.codeconstruct.MCTP1", "/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';
        }
    }, "au.com.codeconstruct.MCTP1", "/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';
        }
    }, "au.com.codeconstruct.MCTP1", "/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("au.com.codeconstruct.MCTP1",
                                   "/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, MctpMessageType::NVME_MI);

    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';
        }
    }, "au.com.codeconstruct.MCTP1", "/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';
        }
    }, "au.com.codeconstruct.MCTP1", "/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, MctpMessageType::NVME_MI);

    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';
        }
    }, "au.com.codeconstruct.MCTP1", "/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';
        }
    }, "au.com.codeconstruct.MCTP1", "/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';
        }
    }, "au.com.codeconstruct.MCTP1", "/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';
        }
    }, "au.com.codeconstruct.MCTP1", "/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
    }

    EXPECT_EQ(queryCompletedCount, 1);

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

// 10. Filter unsupported message types
TEST_F(MctpUtilTest, Filter_UnsupportedMessageType_IsIgnored)
{
    std::string endpointPathSupported =
        "/au/com/codeconstruct/mctp1/networks/1/endpoints/test10_supported";
    std::string endpointPathUnsupported =
        "/au/com/codeconstruct/mctp1/networks/1/endpoints/"
        "test10_unsupported";
    std::string emConfigPath =
        "/xyz/openbmc_project/inventory/system/board/MockBoard/mctp_device";

    setupMctpEndpointListener(conn, MctpMessageType::NVME_MI);

    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++; });

    // 1. Trigger Add for SUPPORTED endpoint (type 4 included)
    std::vector<uint8_t> msgTypesSupported = {2, 0, 4};
    auto m1 = conn->new_method_call("au.com.codeconstruct.MCTP1",
                                    "/au/com/codeconstruct/mctp1",
                                    "com.example.Control", "TriggerAddCustom");
    m1.append(endpointPathSupported, emConfigPath, msgTypesSupported);
    conn->call(m1);

    // 2. Trigger Add for UNSUPPORTED endpoint (no type 4)
    std::vector<uint8_t> msgTypesUnsupported = {2};
    auto m2 = conn->new_method_call("au.com.codeconstruct.MCTP1",
                                    "/au/com/codeconstruct/mctp1",
                                    "com.example.Control", "TriggerAddCustom");
    m2.append(endpointPathUnsupported, emConfigPath, msgTypesUnsupported);
    conn->call(m2);

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

    EXPECT_EQ(queryCompletedCount, 1);

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

    // Verify supported endpoint is present
    auto itSupported = mctpEndpointConfigMap.find(endpointPathSupported);
    EXPECT_NE(itSupported, mctpEndpointConfigMap.end());

    // Verify unsupported endpoint is NOT present
    auto itUnsupported = mctpEndpointConfigMap.find(endpointPathUnsupported);
    EXPECT_EQ(itUnsupported, mctpEndpointConfigMap.end());
}

// 11. MctpReactorDevice creation BEFORE mctpEndpointConfigMap population
// (Deferred Setup)
TEST_F(MctpUtilTest, MctpReactorDevice_DeferredSetup_USB)
{
    std::string endpointPath =
        "/au/com/codeconstruct/mctp1/networks/1/endpoints/11";
    std::string emConfigPath =
        "/xyz/openbmc_project/inventory/system/board/MockBoard/mctp_device";

    setupMctpEndpointListener(conn, MctpMessageType::NVME_MI);

    // Create BusInfo for target device (matching what mock_mctpd.py returns for
    // USB)
    BusInfo targetBusInfo;
    targetBusInfo["BusType"] = "USB";
    targetBusInfo["Port"] = "1.5.1";
    targetBusInfo["Configuration"] = "1";
    targetBusInfo["InterfaceNum"] = "4";
    targetBusInfo["RootHubPath"] = "/sys/devices/platform/ahb/f0806000.usb";

    bool setupCompleted = false;

    // Create MctpReactorDevice
    auto mctpDev = std::make_shared<MctpReactorDevice>(
        conn, emConfigPath, std::vector<BusInfo>{targetBusInfo}, std::nullopt,
        std::nullopt);
    mctpDev->setup([&](const std::error_code& ec,
                       const std::shared_ptr<MctpEndpoint>& ep) {
        setupCompleted = true;
        EXPECT_FALSE(ec);
        EXPECT_NE(ep, nullptr);
    });

    // Verify it didn't complete immediately
    io.poll();
    EXPECT_FALSE(setupCompleted);

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

    // Wait for setup to complete (up to 5 seconds)
    for (int i = 0; i < 50; i++)
    {
        io.poll();
        usleep(100000); // 100ms
        if (setupCompleted)
        {
            break;
        }
    }

    EXPECT_TRUE(setupCompleted);
}

// 12. MctpReactorDevice creation AFTER mctpEndpointConfigMap population
// (Immediate Setup)
TEST_F(MctpUtilTest, MctpReactorDevice_ImmediateSetup_USB)
{
    std::string endpointPath =
        "/au/com/codeconstruct/mctp1/networks/1/endpoints/12";
    std::string emConfigPath =
        "/xyz/openbmc_project/inventory/system/board/MockBoard/mctp_device";

    setupMctpEndpointListener(conn, MctpMessageType::NVME_MI);

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

    // Wait for map to be populated (up to 5 seconds)
    bool populated = false;
    for (int i = 0; i < 50; i++)
    {
        io.poll();
        usleep(100000); // 100ms
        if (mctpEndpointConfigMap.find(endpointPath) !=
            mctpEndpointConfigMap.end())
        {
            populated = true;
            break;
        }
    }
    ASSERT_TRUE(populated);

    // Create BusInfo for target device
    BusInfo targetBusInfo;
    targetBusInfo["BusType"] = "USB";
    targetBusInfo["Port"] = "1.5.1";
    targetBusInfo["Configuration"] = "1";
    targetBusInfo["InterfaceNum"] = "4";
    targetBusInfo["RootHubPath"] = "/sys/devices/platform/ahb/f0806000.usb";

    bool setupCompleted = false;

    // Create MctpReactorDevice
    auto mctpDev = std::make_shared<MctpReactorDevice>(
        conn, emConfigPath, std::vector<BusInfo>{targetBusInfo}, std::nullopt,
        std::nullopt);
    mctpDev->setup([&](const std::error_code& ec,
                       const std::shared_ptr<MctpEndpoint>& ep) {
        setupCompleted = true;
        EXPECT_FALSE(ec);
        EXPECT_NE(ep, nullptr);
    });

    // Verify it completes IMMEDIATELY
    io.poll();
    EXPECT_TRUE(setupCompleted);
}

// 13. MctpReactorDevice removal notification (Case C)
TEST_F(MctpUtilTest, MctpReactorDevice_RemovalNotification_USB)
{
    std::string endpointPath =
        "/au/com/codeconstruct/mctp1/networks/1/endpoints/13";
    std::string emConfigPath =
        "/xyz/openbmc_project/inventory/system/board/MockBoard/mctp_device";

    setupMctpEndpointListener(conn, MctpMessageType::NVME_MI);
    usleep(100000); // 100ms for match rules to register

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

    // Wait for map to be populated
    bool populated = false;
    for (int i = 0; i < 50; i++)
    {
        io.poll();
        usleep(100000); // 100ms
        if (mctpEndpointConfigMap.find(endpointPath) !=
            mctpEndpointConfigMap.end())
        {
            populated = true;
            break;
        }
    }
    ASSERT_TRUE(populated);

    bool sensorNotified = false;

    // Create BusInfo for target device
    BusInfo targetBusInfo;
    targetBusInfo["BusType"] = "USB";
    targetBusInfo["Port"] = "1.5.1";
    targetBusInfo["Configuration"] = "1";
    targetBusInfo["InterfaceNum"] = "4";
    targetBusInfo["RootHubPath"] = "/sys/devices/platform/ahb/f0806000.usb";

    bool setupCompleted = false;
    std::shared_ptr<MctpEndpoint> endpoint;

    // Create MctpReactorDevice
    auto mctpDev = std::make_shared<MctpReactorDevice>(
        conn, emConfigPath, std::vector<BusInfo>{targetBusInfo}, std::nullopt,
        std::nullopt);
    mctpDev->setup([&](const std::error_code& ec,
                       const std::shared_ptr<MctpEndpoint>& ep) {
        setupCompleted = true;
        endpoint = ep;
        EXPECT_FALSE(ec);
        EXPECT_NE(ep, nullptr);
    });

    io.poll();
    ASSERT_TRUE(setupCompleted);
    ASSERT_NE(endpoint, nullptr);

    endpoint->subscribe(
        nullptr, nullptr,
        [&](const std::shared_ptr<MctpEndpoint>&) { sensorNotified = true; });

    // Trigger Remove event!
    std::string removeCmd =
        "busctl call au.com.codeconstruct.MCTP1 /au/com/codeconstruct/mctp1 com.example.Control TriggerRemove s \"" +
        endpointPath + "\"";
    runCmd(removeCmd);

    // Wait for removal notification (up to 5 seconds)
    for (int i = 0; i < 50; i++)
    {
        io.poll();
        usleep(100000); // 100ms
        if (sensorNotified)
        {
            break;
        }
    }

    EXPECT_TRUE(sensorNotified);
}

// 14. Cancellation on Device Removal (Case D)
TEST_F(MctpUtilTest, MctpReactorDevice_Cancellation_USB)
{
    std::string emConfigPath =
        "/xyz/openbmc_project/inventory/system/board/MockBoard/mctp_device";

    setupMctpEndpointListener(conn, MctpMessageType::NVME_MI);

    // Create BusInfo for target device
    BusInfo targetBusInfo;
    targetBusInfo["BusType"] = "USB";
    targetBusInfo["Port"] = "1.5.1";
    targetBusInfo["Configuration"] = "1";
    targetBusInfo["InterfaceNum"] = "4";
    targetBusInfo["RootHubPath"] = "/sys/devices/platform/ahb/f0806000.usb";

    bool setupCompleted = false;
    std::error_code errorResult;

    // Create MctpReactorDevice
    auto mctpDev = std::make_shared<MctpReactorDevice>(
        conn, emConfigPath, std::vector<BusInfo>{targetBusInfo}, std::nullopt,
        std::nullopt);
    mctpDev->setup([&](const std::error_code& ec,
                       const std::shared_ptr<MctpEndpoint>& ep) {
        setupCompleted = true;
        errorResult = ec;
        EXPECT_EQ(ep, nullptr);
    });

    // Verify it didn't complete immediately
    io.poll();
    EXPECT_FALSE(setupCompleted);

    // Call remove() to trigger cancellation!
    mctpDev->remove();

    // Verify it completed with operation_canceled!
    EXPECT_TRUE(setupCompleted);
    EXPECT_EQ(errorResult, std::make_error_code(std::errc::operation_canceled));
}

// 15. Immediate Notification on Device Destruction (Case E)
TEST_F(MctpUtilTest, MctpReactorDevice_DestructionNotification_USB)
{
    std::string endpointPath =
        "/au/com/codeconstruct/mctp1/networks/1/endpoints/14";
    std::string emConfigPath =
        "/xyz/openbmc_project/inventory/system/board/MockBoard/mctp_device";

    setupMctpEndpointListener(conn, MctpMessageType::NVME_MI);
    usleep(100000); // 100ms for match rules to register

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

    // Wait for map to be populated
    bool populated = false;
    for (int i = 0; i < 50; i++)
    {
        io.poll();
        usleep(100000); // 100ms
        if (mctpEndpointConfigMap.find(endpointPath) !=
            mctpEndpointConfigMap.end())
        {
            populated = true;
            break;
        }
    }
    ASSERT_TRUE(populated);

    // Create BusInfo for target device
    BusInfo targetBusInfo;
    targetBusInfo["BusType"] = "USB";
    targetBusInfo["Port"] = "1.5.1";
    targetBusInfo["Configuration"] = "1";
    targetBusInfo["InterfaceNum"] = "4";
    targetBusInfo["RootHubPath"] = "/sys/devices/platform/ahb/f0806000.usb";

    bool sensorNotified = false;
    auto cb = [&](const std::shared_ptr<MctpEndpoint>&) {
        sensorNotified = true;
    };
    {
        bool setupCompleted = false;
        std::shared_ptr<MctpEndpoint> endpoint;

        // Create MctpReactorDevice
        auto mctpDev = std::make_shared<MctpReactorDevice>(
            conn, emConfigPath, std::vector<BusInfo>{targetBusInfo},
            std::nullopt, std::nullopt);

        mctpDev->setup([&](const std::error_code&,
                           const std::shared_ptr<MctpEndpoint>& ep) {
            setupCompleted = true;
            endpoint = ep;
        });

        io.poll();
        ASSERT_TRUE(setupCompleted);
        ASSERT_NE(endpoint, nullptr);

        endpoint->subscribe(nullptr, nullptr, cb);
    }

    // mctpDev is destroyed here. Wait for the removal notification to be
    // processed.
    int i = 0;
    for (; i < 50; i++)
    {
        io.poll();
        usleep(100000); // 100ms
        if (sensorNotified)
        {
            break;
        }
    }

    ASSERT_LT(i, 50) << "Timeout: Destruction notification was never fired!";
    EXPECT_TRUE(sensorNotified);
}

// 16. Bridged Endpoint Resolution
TEST_F(MctpUtilTest, BridgedEndpoint_ResolvesParentBridge)
{
    std::string bridgePath =
        "/au/com/codeconstruct/mctp1/networks/1/endpoints/mctp_device";
    std::string bridgeEmPath =
        "/xyz/openbmc_project/inventory/system/board/MockBoard/mctp_device";
    std::string endpointPath =
        "/au/com/codeconstruct/mctp1/networks/1/endpoints/test_bridged";
    std::string emConfigPath =
        "/xyz/openbmc_project/inventory/system/board/MockBoard/bridged_endpoint_config";

    setupMctpEndpointListener(conn, MctpMessageType::NVME_MI);

    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();

    std::string addBridgeCmd =
        "busctl call au.com.codeconstruct.MCTP1 /au/com/codeconstruct/mctp1 com.example.Control TriggerAdd ss \"" +
        bridgePath + "\" \"" + bridgeEmPath + "\"";
    runCmd(addBridgeCmd);

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

    // Wait for mapperx to create association for bridge
    bool found = false;
    for (int i = 0; i < 50; i++)
    {
        if (checkPathInMapper(bridgePath + "/configured_by"))
        {
            found = true;
            break;
        }
        io.poll();
        usleep(100000); // 100ms
    }
    ASSERT_TRUE(found) << "Timed out waiting for bridge association in mapper";

    // 2. Trigger Add for Endpoint!
    std::string addEpCmd =
        "busctl call au.com.codeconstruct.MCTP1 /au/com/codeconstruct/mctp1 com.example.Control TriggerAdd ss \"" +
        endpointPath + "\" \"" + emConfigPath + "\"";
    runCmd(addEpCmd);

    // Wait for endpoint query to complete
    for (int i = 0; i < 50; i++)
    {
        io.poll();
        usleep(100000); // 100ms
        if (queryCompletedCount >= 2)
        {
            break;
        }
    }
    EXPECT_EQ(queryCompletedCount, 2);

    auto it = mctpEndpointConfigMap.find(endpointPath);
    ASSERT_NE(it, mctpEndpointConfigMap.end());
    EXPECT_EQ(it->second.size(), 2);

    MctpReactorBusInfo busInfo(it->second);
    EXPECT_TRUE(busInfo.isValid());
    EXPECT_EQ(busInfo.getType().front(), "USB");
    EXPECT_EQ(busInfo.getProperties().front().at("Port"), "1.5.1");
}

// 17. Broken Bridge Chain (Non-existent bridge)
TEST_F(MctpUtilTest, BridgedEndpoint_BrokenChain_Nonexistent_Fails)
{
    std::string endpointPath =
        "/au/com/codeconstruct/mctp1/networks/1/endpoints/test_broken_nonexistent";
    std::string emConfigPath =
        "/xyz/openbmc_project/inventory/system/board/MockBoard/broken_endpoint_nonexistent";

    setupMctpEndpointListener(conn, MctpMessageType::NVME_MI);

    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();

    std::string addCmd =
        "busctl call au.com.codeconstruct.MCTP1 /au/com/codeconstruct/mctp1 com.example.Control TriggerAdd ss \"" +
        endpointPath + "\" \"" + emConfigPath + "\"";
    runCmd(addCmd);

    for (int i = 0; i < 50; i++)
    {
        io.poll();
        usleep(100000); // 100ms
        if (queryCompletedCount >= 1)
        {
            break;
        }
    }
    EXPECT_EQ(queryCompletedCount, 1);

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

// 18. Multi-Level Bridging
TEST_F(MctpUtilTest, BridgedEndpoint_MultiLevel_ResolvesRootBridge)
{
    std::string rootBridgePath =
        "/au/com/codeconstruct/mctp1/networks/1/endpoints/mctp_device";
    std::string rootBridgeEmPath =
        "/xyz/openbmc_project/inventory/system/board/MockBoard/mctp_device";
    std::string interBridgePath =
        "/au/com/codeconstruct/mctp1/networks/1/endpoints/intermediate_bridge";
    std::string interBridgeEmPath =
        "/xyz/openbmc_project/inventory/system/board/MockBoard/intermediate_bridge";
    std::string endpointPath =
        "/au/com/codeconstruct/mctp1/networks/1/endpoints/test_multilevel";
    std::string emConfigPath =
        "/xyz/openbmc_project/inventory/system/board/MockBoard/multilevel_endpoint";

    setupMctpEndpointListener(conn, MctpMessageType::NVME_MI);

    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();

    // 1. Trigger Add for Root Bridge!
    std::string addRootCmd =
        "busctl call au.com.codeconstruct.MCTP1 /au/com/codeconstruct/mctp1 com.example.Control TriggerAdd ss \"" +
        rootBridgePath + "\" \"" + rootBridgeEmPath + "\"";
    runCmd(addRootCmd);

    // Wait for root bridge query to complete
    for (int i = 0; i < 50; i++)
    {
        io.poll();
        usleep(100000); // 100ms
        if (queryCompletedCount >= 1)
        {
            break;
        }
    }
    ASSERT_EQ(queryCompletedCount, 1);

    // 2. Trigger Add for Intermediate Bridge!
    std::string addInterCmd =
        "busctl call au.com.codeconstruct.MCTP1 /au/com/codeconstruct/mctp1 com.example.Control TriggerAdd ss \"" +
        interBridgePath + "\" \"" + interBridgeEmPath + "\"";
    runCmd(addInterCmd);

    // Wait for intermediate bridge query to complete
    for (int i = 0; i < 50; i++)
    {
        io.poll();
        usleep(100000); // 100ms
        if (queryCompletedCount >= 2)
        {
            break;
        }
    }
    ASSERT_EQ(queryCompletedCount, 2);

    // 3. Trigger Add for Endpoint!
    std::string addEpCmd =
        "busctl call au.com.codeconstruct.MCTP1 /au/com/codeconstruct/mctp1 com.example.Control TriggerAdd ss \"" +
        endpointPath + "\" \"" + emConfigPath + "\"";
    runCmd(addEpCmd);

    // Wait for endpoint query to complete
    for (int i = 0; i < 50; i++)
    {
        io.poll();
        usleep(100000); // 100ms
        if (queryCompletedCount >= 3)
        {
            break;
        }
    }
    EXPECT_EQ(queryCompletedCount, 3);

    auto it = mctpEndpointConfigMap.find(endpointPath);
    ASSERT_NE(it, mctpEndpointConfigMap.end());
    EXPECT_EQ(it->second.size(), 3);

    MctpReactorBusInfo busInfo(it->second);
    EXPECT_TRUE(busInfo.isValid());
    EXPECT_EQ(busInfo.getType().front(), "USB");
    EXPECT_EQ(busInfo.getProperties().front().at("Port"), "1.5.1");
}

// 19. Out-of-Order Triggers (Endpoint before Bridge) - Expect Success after
// Retry
TEST_F(MctpUtilTest, BridgedEndpoint_OutOfOrder_SucceedsAfterRetry)
{
    std::string bridgePath =
        "/au/com/codeconstruct/mctp1/networks/1/endpoints/mctp_device";
    std::string bridgeEmPath =
        "/xyz/openbmc_project/inventory/system/board/MockBoard/mctp_device";
    std::string endpointPath =
        "/au/com/codeconstruct/mctp1/networks/1/endpoints/test_out_of_order";
    std::string emConfigPath =
        "/xyz/openbmc_project/inventory/system/board/MockBoard/bridged_endpoint_config";

    setupMctpEndpointListener(conn, MctpMessageType::NVME_MI);

    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
    io.poll();
    usleep(100000); // 100ms
    io.poll();

    // Wait 5 seconds to ensure cooldown expires!
    for (int i = 0; i < 50; i++)
    {
        io.poll();
        usleep(100000); // 100ms
    }

    // 1. Trigger Add for Endpoint FIRST!
    std::string addEpCmd =
        "busctl call au.com.codeconstruct.MCTP1 /au/com/codeconstruct/mctp1 com.example.Control TriggerAdd ss \"" +
        endpointPath + "\" \"" + emConfigPath + "\"";
    runCmd(addEpCmd);

    // Trigger Add for Bridge SECOND (after 2s)!
    for (int i = 0; i < 20; i++)
    {
        io.poll();
        usleep(100000); // 100ms
    }
    std::string addBridgeCmd =
        "busctl call au.com.codeconstruct.MCTP1 /au/com/codeconstruct/mctp1 com.example.Control TriggerAdd ss \"" +
        bridgePath + "\" \"" + bridgeEmPath + "\"";
    runCmd(addBridgeCmd);

    // Wait for all to complete!
    // B retries after 5 seconds, so it should complete around 6-7 seconds!
    for (int i = 0; i < 100; i++)
    {                   // 10 seconds max
        io.poll();
        usleep(100000); // 100ms
    }

    // Expect 3 queries: B (fail) -> Bridge A (success) -> B (success retry)
    EXPECT_EQ(queryCompletedCount, 3);

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

// 20. performEmConfigQuery Failure Triggers Retry - Expect Failure with Current
// Code
TEST_F(MctpUtilTest, performEmConfigQuery_Failure_TriggersRetry)
{
    std::string endpointPath =
        "/au/com/codeconstruct/mctp1/networks/1/endpoints/test_retry";
    std::string emConfigPath =
        "/xyz/openbmc_project/inventory/system/board/MockBoard/mctp_device";

    setupMctpEndpointListener(conn, MctpMessageType::NVME_MI);

    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
    for (int i = 0; i < 50; i++)
    {
        io.poll();
        usleep(100000); // 100ms
    }

    // Enable failure mode in mock!
    runCmd(
        "busctl call xyz.openbmc_project.EntityManager /xyz/openbmc_project/inventory com.example.Control SetFailMode b true");

    // Trigger Add for Endpoint!
    std::string addCmd =
        "busctl call au.com.codeconstruct.MCTP1 /au/com/codeconstruct/mctp1 com.example.Control TriggerAdd ss \"" +
        endpointPath + "\" \"" + emConfigPath + "\"";
    runCmd(addCmd);

    // Wait for first query to complete (it should fail!)
    for (int i = 0; i < 20; i++)
    {
        io.poll();
        usleep(100000); // 100ms
        if (queryCompletedCount >= 1)
        {
            break;
        }
    }
    EXPECT_EQ(queryCompletedCount, 1);

    // Disable failure mode in mock!
    runCmd(
        "busctl call xyz.openbmc_project.EntityManager /xyz/openbmc_project/inventory com.example.Control SetFailMode b false");

    // Wait for retry!
    // With current code, it won't retry on failure! So count will stay 1!
    // With fix, it should retry after 5 seconds and succeed!
    // So count should reach 2!
    for (int i = 0; i < 80; i++)
    {                   // 8 seconds max
        io.poll();
        usleep(100000); // 100ms
        if (queryCompletedCount >= 2)
        {
            break;
        }
    }

    // Expect success (count=2) after fix, but FAIL with current code!
    EXPECT_EQ(queryCompletedCount, 2);

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

// 21. Priming with failing endpoint does not block others
TEST_F(MctpUtilTest, Priming_FailingEndpoint_DoesNotBlockOthers)
{
    std::string endpointPathFail =
        "/au/com/codeconstruct/mctp1/networks/1/endpoints/test_prime_fail";
    std::string emConfigPathFail =
        "/xyz/openbmc_project/inventory/system/board/MockBoard/broken_endpoint_nonexistent";

    std::string endpointPathSuccess =
        "/au/com/codeconstruct/mctp1/networks/1/endpoints/test_prime_success";
    std::string emConfigPathSuccess =
        "/xyz/openbmc_project/inventory/system/board/MockBoard/mctp_device";

    // Pre-populate association for failing endpoint BEFORE listener starts!
    auto m = conn->new_method_call("au.com.codeconstruct.MCTP1",
                                   "/au/com/codeconstruct/mctp1",
                                   "com.example.Control", "TriggerAdd");
    m.append(endpointPathFail, emConfigPathFail);
    conn->call(m);

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

    // Now setup listener (this starts priming!)
    setupMctpEndpointListener(conn, MctpMessageType::NVME_MI);

    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 query to start for failing endpoint
    usleep(500000); // 500ms
    io.poll();

    // Trigger Add for a VALID endpoint while priming is in progress!
    std::string addCmd =
        "busctl call au.com.codeconstruct.MCTP1 /au/com/codeconstruct/mctp1 com.example.Control TriggerAdd ss \"" +
        endpointPathSuccess + "\" \"" + emConfigPathSuccess + "\"";
    runCmd(addCmd);

    // Wait for queries to complete.
    // With fix: failing one fails and defers, valid one succeeds! Total = 2
    // queries. Without fix: failing one hangs, valid one never starts! Total =
    // 1 query.

    for (int i = 0; i < 150; i++)
    {                   // 15 seconds max
        io.poll();
        usleep(100000); // 100ms
        if (mctpEndpointConfigMap.find(endpointPathSuccess) !=
            mctpEndpointConfigMap.end())
        {
            break;
        }
    }

    auto it = mctpEndpointConfigMap.find(endpointPathSuccess);
    EXPECT_NE(it, mctpEndpointConfigMap.end());
}

// 22. MctpReactorBusInfo chain parsing and operator== matching
TEST_F(MctpUtilTest, MctpReactorBusInfo_ChainParsingAndMatching)
{
    std::vector<SensorData> chain;

    // Leaf (endpoint)
    SensorBaseConfigMap epProps;
    epProps["EIDOffset"] = uint64_t(2);
    SensorData epData;
    epData["xyz.openbmc_project.Configuration.MCTPBridgeDownstreamDevice"] =
        epProps;
    chain.push_back(epData);

    // Bridge
    SensorBaseConfigMap bridgeProps;
    bridgeProps["BusType"] = std::string("USB");
    bridgeProps["Port"] = std::string("1.5.1");
    bridgeProps["Configuration"] =
        std::string("1"); // Extra property not in target
    SensorData bridgeData;
    bridgeData["xyz.openbmc_project.Configuration.MCTPUSBDevice"] = bridgeProps;
    chain.push_back(bridgeData);

    MctpReactorBusInfo busInfo(chain);

    EXPECT_TRUE(busInfo.isValid());
    const auto& propsList = busInfo.getProperties();
    ASSERT_EQ(propsList.size(), 2);

    // Verify order is root-to-leaf (from Test 22)
    EXPECT_EQ(propsList[0].at("BusType"), "USB");
    EXPECT_EQ(propsList[0].at("Port"), "1.5.1");

    EXPECT_EQ(propsList[1].at("BusType"), "MCTP Bridge");
    EXPECT_EQ(propsList[1].at("EIDOffset"), "2");

    // Verify operator== subset matching (from Test 23)
    std::vector<BusInfo> targetConfig;

    // Root level
    BusInfo targetBridge;
    targetBridge["BusType"] = "USB";
    targetBridge["Port"] = "1.5.1";
    targetConfig.push_back(targetBridge);

    // Leaf level
    BusInfo targetEp;
    targetEp["EIDOffset"] = "2";
    targetConfig.push_back(targetEp);

    // Should match because target is a subset of extracted properties
    EXPECT_TRUE(busInfo == targetConfig);

    // Test mismatch in value
    targetConfig[1]["EIDOffset"] = "3";
    EXPECT_FALSE(busInfo == targetConfig);

    // Test missing property in extracted props
    targetConfig[1]["EIDOffset"] = "2";
    targetConfig[1]["ExtraProp"] = "value";
    EXPECT_FALSE(busInfo == targetConfig);

    // Test size mismatch
    targetConfig.pop_back();
    EXPECT_FALSE(busInfo == targetConfig);
}

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