#include "MctpUtil.hpp"

#include "absl/strings/match.h"

#include "Utils.hpp"
#include "VariantVisitors.hpp"

#include <boost/asio/steady_timer.hpp>
#include <boost/container/flat_map.hpp>
#include <phosphor-logging/lg2.hpp>
#include <sdbusplus/bus/match.hpp>

#include <chrono>
#include <filesystem>
#include <string>

std::map<std::string, SensorData> mctpEndpointConfigMap;

enum class State : uint8_t
{
    None,
    Add,
    Remove
};

struct EndpointState
{
    State state = State::None;
    bool querying = false;
};

static std::map<std::string, EndpointState> endpointStates;

static std::unique_ptr<sdbusplus::bus::match_t> associationMatch = nullptr;
static std::unique_ptr<sdbusplus::bus::match_t> associationRemoveMatch =
    nullptr;

static void performEmConfigQuery(
    const std::shared_ptr<sdbusplus::asio::connection>& conn,
    const std::string& endpointPath, const std::string& emConfigPath)
{
    conn->async_method_call(
        [conn, endpointPath, emConfigPath](const boost::system::error_code& ec,
                                           const ManagedObjectType& objects) {
        auto& state = endpointStates[endpointPath];
        state.querying = false;

        State lastState = state.state;
        state.state = State::None; // Reset for next query

        if (lastState == State::Remove)
        {
            lg2::info("Ignoring query reply for removed endpoint {ENDPOINT}",
                      "ENDPOINT", endpointPath);
            auto it = mctpEndpointConfigMap.find(endpointPath);
            if (it != mctpEndpointConfigMap.end())
            {
                mctpEndpointConfigMap.erase(it);
            }
            return;
        }

        if (ec)
        {
            lg2::error("Failed to get managed objects for {PATH}: {ERROR}",
                       "PATH", emConfigPath, "ERROR", ec.message());
            return;
        }

        auto objIt =
            objects.find(sdbusplus::message::object_path(emConfigPath));

        if (objIt == objects.end())
        {
            lg2::warning("EM config path {PATH} not found in managed objects",
                         "PATH", emConfigPath);
            return;
        }

        if (!objIt->second.empty())
        {
            lg2::info(
                "Recorded MCTP endpoint {ENDPOINT} with config from {PATH}",
                "ENDPOINT", endpointPath, "PATH", emConfigPath);
            mctpEndpointConfigMap[endpointPath] = objIt->second;
            lg2::info("DEBUG: Map populated, new size: {SIZE}", "SIZE",
                      mctpEndpointConfigMap.size());
        }

        if (lastState == State::Add)
        {
            lg2::info(
                "DEBUG: Triggering deferred query for endpoint {ENDPOINT}",
                "ENDPOINT", endpointPath);
            state.querying = true;
            performEmConfigQuery(conn, endpointPath, emConfigPath);
        }
    },
        "xyz.openbmc_project.EntityManager", "/xyz/openbmc_project/inventory",
        "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
}

void setupMctpEndpointListener(
    const std::shared_ptr<sdbusplus::asio::connection>& conn)
{
    // Match 1: Listen for Associations from mctp-reactor
    const std::string associationMatchSpec =
        "type='signal',interface='org.freedesktop.DBus.ObjectManager',member='InterfacesAdded',arg0path='/au/com/codeconstruct/mctp1/'";

    associationMatch = std::make_unique<sdbusplus::bus::match_t>(
        static_cast<sdbusplus::bus_t&>(*conn), associationMatchSpec,
        [conn](sdbusplus::message_t& msg) {
        sdbusplus::message::object_path path;
        boost::container::flat_map<
            std::string,
            boost::container::flat_map<
                std::string,
                std::variant<std::string, std::vector<std::string>>>>
            interfaces;
        msg.read(path, interfaces);
        lg2::info("DEBUG: InterfacesAdded callback for {PATH}", "PATH",
                  path.str);

        auto it = interfaces.find("xyz.openbmc_project.Association");
        if (it == interfaces.end())
        {
            return;
        }

        auto propIt = it->second.find("endpoints");
        if (propIt == it->second.end())
        {
            return;
        }

        const auto* endpoints =
            std::get_if<std::vector<std::string>>(&propIt->second);
        if (!endpoints || endpoints->empty())
        {
            return;
        }

        std::string emConfigPath = endpoints->front();

        std::string endpointPath = path.str;
        constexpr std::string_view suffix = "/configured_by";
        if (endpointPath.ends_with("/configured_by"))
        {
            endpointPath =
                endpointPath.substr(0, endpointPath.size() - suffix.length());
        }

        auto& state = endpointStates[endpointPath];

        if (state.querying)
        {
            state.state = State::Add;
            return;
        }

        state.querying = true;
        performEmConfigQuery(conn, endpointPath, emConfigPath);
    });

    const std::string associationRemoveMatchSpec =
        "type='signal',interface='org.freedesktop.DBus.ObjectManager',member='InterfacesRemoved',arg0path='/au/com/codeconstruct/mctp1/'";

    associationRemoveMatch = std::make_unique<sdbusplus::bus::match_t>(
        static_cast<sdbusplus::bus_t&>(*conn), associationRemoveMatchSpec,
        [](sdbusplus::message_t& msg) {
        sdbusplus::message::object_path path;
        std::vector<std::string> interfaces;
        msg.read(path, interfaces);

        std::string endpointPath = path.str;
        constexpr std::string_view suffix = "/configured_by";
        if (endpointPath.ends_with("/configured_by"))
        {
            endpointPath =
                endpointPath.substr(0, endpointPath.size() - suffix.length());
        }

        auto& state = endpointStates[endpointPath];

        if (state.querying)
        {
            state.state = State::Remove;
        }
        else
        {
            auto it = mctpEndpointConfigMap.find(endpointPath);
            if (it != mctpEndpointConfigMap.end())
            {
                lg2::info("Removing MCTP endpoint {ENDPOINT} from map",
                          "ENDPOINT", endpointPath);
                mctpEndpointConfigMap.erase(it);
            }
        }
    });

    // Prime the cache: Query existing Associations
    constexpr auto associationInterfaces =
        std::to_array({"xyz.openbmc_project.Association"});
    conn->async_method_call(
        [conn](const boost::system::error_code& ec,
               const GetSubTreeType& subtree) {
        if (ec)
        {
            lg2::error("Failed to get associations from Object Mapper: {ERROR}",
                       "ERROR", ec.message());
            return;
        }

        for (const auto& [path, services] : subtree)
        {
            if (!path.ends_with("/configured_by"))
            {
                continue;
            }

            conn->async_method_call(
                [conn,
                 path](const boost::system::error_code& ec,
                       const std::variant<std::vector<std::string>>& value) {
                if (ec)
                {
                    lg2::error("Failed to get endpoints for {PATH}: {ERROR}",
                               "PATH", path, "ERROR", ec.message());
                    return;
                }

                const auto* endpoints =
                    std::get_if<std::vector<std::string>>(&value);
                if (!endpoints || endpoints->empty())
                {
                    return;
                }

                std::string emConfigPath = endpoints->front();
                std::string endpointPath = path;
                constexpr std::string_view suffix = "/configured_by";
                if (endpointPath.ends_with("/configured_by"))
                {
                    endpointPath = endpointPath.substr(0, endpointPath.size() -
                                                              suffix.length());
                }

                auto& state = endpointStates[endpointPath];

                if (state.querying)
                {
                    state.state = State::Add;
                    return;
                }

                state.querying = true;
                performEmConfigQuery(conn, endpointPath, emConfigPath);
            },
                "xyz.openbmc_project.ObjectMapper", path,
                "org.freedesktop.DBus.Properties", "Get",
                "xyz.openbmc_project.Association", "endpoints");
        }
    },
        "xyz.openbmc_project.ObjectMapper",
        "/xyz/openbmc_project/object_mapper",
        "xyz.openbmc_project.ObjectMapper", "GetSubTree",
        "/au/com/codeconstruct/mctp1", 0, associationInterfaces);
}

BusInfo extractBusInfo(const SensorData& configData)
{
    BusInfo busInfo;
    auto extractProp = [](const auto& properties, BusInfo& info,
                          const std::string& key) {
        auto it = properties.find(key);
        if (it != properties.end())
        {
            info[key] = std::visit(VariantToStringVisitor(), it->second);
        }
    };

    for (const auto& [intf, props] : configData)
    {
        if (absl::StrContains(intf,
                              "xyz.openbmc_project.Configuration.BusInfo"))
        {
            std::string busType;
            auto it = props.find("BusType");
            if (it != props.end())
            {
                busType = std::visit(VariantToStringVisitor(), it->second);
            }

            if (busType == "USB")
            {
                extractProp(props, busInfo, "RootHubPath");
                extractProp(props, busInfo, "Port");
                extractProp(props, busInfo, "Configuration");
                extractProp(props, busInfo, "InterfaceNum");

                busInfo["BusType"] = busType;
            }
            else if (!busType.empty())
            {
                lg2::warning("Unsupported BusType {TYPE}", "TYPE", busType);
            }
        }
    }
    return busInfo;
}

void cleanupMctpEndpointListener()
{
    associationMatch.reset();
    associationRemoveMatch.reset();
}
