|  | #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; | 
|  | }; |