#include "topology.hpp"

#include "phosphor-logging/lg2.hpp"

void Topology::addBoard(const std::string& path, const std::string& boardType,
                        const std::string& boardName,
                        const nlohmann::json& exposesItem)
{
    auto findType = exposesItem.find("Type");
    if (findType == exposesItem.end())
    {
        return;
    }

    boardNames.try_emplace(boardName, path);

    PortType exposesType = findType->get<std::string>();

    if (exposesType == "DownstreamPort")
    {
        addDownstreamPort(path, exposesItem);
    }
    else if (exposesType.ends_with("Port"))
    {
        upstreamPorts[exposesType].insert(path);
    }
    else
    {
        return;
    }
    boardTypes[path] = boardType;
}

void Topology::addDownstreamPort(const Path& path,
                                 const nlohmann::json& exposesItem)
{
    auto findConnectsTo = exposesItem.find("ConnectsToType");
    if (findConnectsTo == exposesItem.end())
    {
        lg2::error("Board at path {PATH} is missing ConnectsToType", "PATH",
                   path);
        return;
    }
    PortType connectsTo = findConnectsTo->get<std::string>();

    downstreamPorts[connectsTo].insert(path);
    auto findPoweredBy = exposesItem.find("PowerPort");
    if (findPoweredBy != exposesItem.end())
    {
        powerPaths.insert(path);
    }
}

std::unordered_map<std::string, std::set<Association>> Topology::getAssocs(
    BoardPathsView boardPaths)
{
    std::unordered_map<std::string, std::set<Association>> result;

    // look at each upstream port type
    for (const auto& upstreamPortPair : upstreamPorts)
    {
        auto downstreamMatch = downstreamPorts.find(upstreamPortPair.first);

        if (downstreamMatch == downstreamPorts.end())
        {
            // no match
            continue;
        }

        fillAssocsForPortId(result, boardPaths, upstreamPortPair.second,
                            downstreamMatch->second);
    }
    return result;
}

void Topology::fillAssocsForPortId(
    std::unordered_map<std::string, std::set<Association>>& result,
    BoardPathsView boardPaths, const std::set<Path>& upstreamPaths,
    const std::set<Path>& downstreamPaths)
{
    for (const Path& upstream : upstreamPaths)
    {
        for (const Path& downstream : downstreamPaths)
        {
            fillAssocForPortId(result, boardPaths, upstream, downstream);
        }
    }
}

void Topology::fillAssocForPortId(
    std::unordered_map<std::string, std::set<Association>>& result,
    BoardPathsView boardPaths, const Path& upstream, const Path& downstream)
{
    if (boardTypes[upstream] != "Chassis" && boardTypes[upstream] != "Board")
    {
        return;
    }
    // The downstream path must be one we care about.
    if (!std::ranges::contains(boardPaths, downstream))
    {
        return;
    }

    std::string assoc = "contained_by";
    std::optional<std::string> opposite = getOppositeAssoc(assoc);

    if (!opposite.has_value())
    {
        return;
    }

    result[downstream].insert({assoc, opposite.value(), upstream});

    if (powerPaths.contains(downstream))
    {
        assoc = "powering";
        opposite = getOppositeAssoc(assoc);
        if (!opposite.has_value())
        {
            return;
        }

        result[downstream].insert({assoc, opposite.value(), upstream});
    }
}

const std::set<std::pair<std::string, std::string>> assocs = {
    {"powering", "powered_by"}, {"containing", "contained_by"},
    // ... extend as needed
};

std::optional<std::string> Topology::getOppositeAssoc(
    const AssocName& assocName)
{
    for (const auto& entry : assocs)
    {
        if (entry.first == assocName)
        {
            return entry.second;
        }
        if (entry.second == assocName)
        {
            return entry.first;
        }
    }

    return std::nullopt;
}

void Topology::remove(const std::string& boardName)
{
    // Remove the board from boardNames, and then using the path
    // found in boardNames remove it from upstreamPorts and
    // downstreamPorts.
    auto boardFind = boardNames.find(boardName);
    if (boardFind == boardNames.end())
    {
        return;
    }

    std::string boardPath = boardFind->second;

    boardNames.erase(boardFind);

    for (auto& upstreamPort : upstreamPorts)
    {
        upstreamPort.second.erase(boardPath);
    }

    for (auto& downstreamPort : downstreamPorts)
    {
        downstreamPort.second.erase(boardPath);
    }
}
