#include "requirementManager.h"

#include "requirementItem.h"

#include <sdi_toolBox/generic/uuid.h>

using namespace std;
using namespace core::project;
//--------------------------------------------------------------
/* Default constructor */
RequirementManager::RequirementManager()
{
  m_rootRequirement = make_shared<RequirementItem>(*this);     // Create the root requirement item and set it as the root requirement
}
//--------------------------------------------------------------
/* Get the root requirement */
RequirementManager::RequirementItemPtr RequirementManager::getRootRequirement() const
{
  return m_rootRequirement;     // Return the root requirement item pointer
}
//--------------------------------------------------------------
/* Get the vector of child requirement items of the root requirement */
std::vector<RequirementManager::RequirementItemPtr> RequirementManager::getRootRequirementChild() const
{
  return m_rootRequirement->getChildren();     // Return the vector of child requirement items of the root requirement
}
//--------------------------------------------------------------
/* Get a requirement by its UUID */
RequirementManager::RequirementItemPtr RequirementManager::getRequirement(const std::string &uuid) const
{
  if (m_requirementsByUuid.contains(uuid))
    return m_requirementsByUuid.at(uuid);     // Return the requirement item pointer if found in the map
  return {};                                  // Return nullptr if the requirement with the given UUID is not found
}
//--------------------------------------------------------------
/* Get the vector of child requirement items of a requirement by its UUID */
std::vector<RequirementManager::RequirementItemPtr> RequirementManager::getRequirementChildren(const std::string &uuid) const
{
  if (m_requirementsByUuid.contains(uuid))
    return m_requirementsByUuid.at(uuid)->getChildren();     // Return the vector of child requirement items if the requirement with the given UUID is found in the map
  return {};                                                 // Return an empty vector if the requirement with the given UUID is not found
}
//--------------------------------------------------------------
/* Generate a unique UUID string that is not already registered in the manager's internal map */
std::string RequirementManager::generateUniqueUuid() const
{
  std::string uuid;
  do
  {
    uuid = sdi_toolBox::generic::UuidGenerator::uuid_v4();     // Generate a random UUID v4 string
  } while (isRequirementRegistered(uuid));     // Check if the generated UUID is already registered

  return uuid;     // Return the unique UUID string
}
//--------------------------------------------------------------
/* Check if a requirement with the given UUID is registered in the manager's internal map */
bool RequirementManager::isRequirementRegistered(const std::string &uuid) const
{
  return m_requirementsByUuid.contains(uuid);
}
//--------------------------------------------------------------
/* Register a requirement in the manager's internal map for quick lookup by UUID */
void RequirementManager::registerRequirement(const RequirementItemPtr &requirement)
{
  m_requirementsByUuid[requirement->metadata.uuid] = requirement;
}
//--------------------------------------------------------------
/* Unregister a requirement from the manager's internal map */
void RequirementManager::unregisterRequirement(const std::string &uuid)
{
  m_requirementsByUuid.erase(uuid);
}
//--------------------------------------------------------------