#pragma once

#include <nlohmann/json.hpp>

#include <set>
#include <unordered_map>

using Association = std::tuple<std::string, std::string, std::string>;

using BoardPathsView = decltype(std::views::keys(
    std::declval<std::map<std::string, std::string>&>()));

class AssocName
{
  public:
    std::string name;
    std::string reverse;

    AssocName(const std::string& name, const std::string& reverse,
              const std::set<std::string>& allowedOnBoardTypes,
              const std::set<std::string>& allowedOnBoardTypesReverse);
    AssocName() = delete;

    // The type (e.g. Chassis, Board, Valve, ...) on which the association is
    // allowed
    std::set<std::string> allowedOnBoardTypes;

    // The type (e.g. Chassis, Board, Valve, ...) on which the reverse
    // association is allowed
    std::set<std::string> allowedOnBoardTypesReverse;

    AssocName getReverse() const;

    bool operator==(const AssocName& other) const = default;
    bool operator<(const AssocName& other) const;
};

extern const std::vector<AssocName> supportedAssocs;

class Topology
{
  public:
    explicit Topology() = default;

    void addBoard(const std::string& path, const std::string& boardType,
                  const std::string& boardName,
                  const nlohmann::json& exposesItem);
    std::unordered_map<std::string, std::set<Association>> getAssocs(
        BoardPathsView boardPaths);
    void remove(const std::string& boardName);

  private:
    using Path = std::string;
    using BoardType = std::string;
    using BoardName = std::string;
    using PortType = std::string;

    void addDownstreamPort(const Path& path, const nlohmann::json& exposesItem);

    // @brief: fill associations map with the associations for a port identifier
    // such as 'MB Upstream Port'
    void fillAssocsForPortId(
        std::unordered_map<std::string, std::set<Association>>& result,
        BoardPathsView boardPaths,
        const std::map<Path, std::set<AssocName>>& pathAssocs);

    void fillAssocForPortId(
        std::unordered_map<std::string, std::set<Association>>& result,
        BoardPathsView boardPaths, const Path& upstream, const Path& downstream,
        const AssocName& assocName);

    void addConfiguredPort(const Path& path, const nlohmann::json& exposesItem);
    void addPort(const PortType& port, const Path& path,
                 const AssocName& assocName);

    static std::optional<AssocName> getAssocByName(const std::string& name);

    // Maps the port name to the participating paths.
    // each path also has their role(s) in the association.
    // For example a PSU path which is part of "MB Upstream Port"
    // will have "powering" role.
    std::unordered_map<PortType, std::map<Path, std::set<AssocName>>> ports;

    std::unordered_map<Path, BoardType> boardTypes;
    std::unordered_map<BoardName, Path> boardNames;
};
