#pragma once

#include <memory>
#include <string>
#include <unordered_map>

namespace core::project
{
class RequirementItem;
//--------------------------------------------------------------
class RequirementManager
{
  using RequirementItemPtr = std::shared_ptr<RequirementItem>;

  public:
  RequirementManager();                                                           // Default constructor
  virtual ~RequirementManager()                                    = default;     // Default destructor
  RequirementManager(const RequirementManager &obj)                = delete;      // Copy constructor
  RequirementManager(RequirementManager &&obj) noexcept            = delete;      // Move constructor
  RequirementManager &operator=(const RequirementManager &obj)     = delete;      // Copy assignment operator
  RequirementManager &operator=(RequirementManager &&obj) noexcept = delete;      // Move assignment operator

  [[nodiscard]] RequirementItemPtr              getRootRequirement() const;          // Get the root requirement
  [[nodiscard]] std::vector<RequirementItemPtr> getRootRequirementChild() const;     // Get the vector of child requirement items of the root requirement

  [[nodiscard]] RequirementItemPtr              getRequirement(const std::string &uuid) const;             // Get a requirement by its UUID
  [[nodiscard]] std::vector<RequirementItemPtr> getRequirementChildren(const std::string &uuid) const;     // Get the vector of child requirement items of a requirement by its UUID

  // Requirement management functions
  [[nodiscard]] std::string generateUniqueUuid() const;                                     // Generate a unique UUID string that is not already registered in the manager's internal map
  [[nodiscard]] bool        isRequirementRegistered(const std::string &uuid) const;         // Check if a requirement with the given UUID is registered in the manager's internal map
  void                      registerRequirement(const RequirementItemPtr &requirement);     // Register a requirement in the manager's internal map for quick lookup by UUID
  void                      unregisterRequirement(const std::string &uuid);                 // Unregister a requirement from the manager's internal map

  protected:
  RequirementItemPtr                                  m_rootRequirement;        // Root requirement of the current project
  std::unordered_map<std::string, RequirementItemPtr> m_requirementsByUuid;     // Map of requirement UUID to requirement pointer for quick lookup
};
//--------------------------------------------------------------
}     // namespace core::project
