#pragma once

#include <api/project.h>
#include <api/requirement.h>
#include <dBus/dBus.h>
#include <memory>
#include <thread>

namespace core::project
{
class ProjectData;
//--------------------------------------------------------------
class ProjectManager : public dBus::Node
{
  using ProjectPtr = std::shared_ptr<ProjectData>;

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

  explicit ProjectManager(dBus::Bus &bus);     // Constructor

  protected:
  std::filesystem::path m_filePath;     // Path of the currently opened project file

  ProjectPtr m_projectData;     // Current project data, including the root requirement and all its sub-requirements

  private:
  void openFile(const std::filesystem::path &filePath);          // Open a project file and load the requirements
  void saveFile(const std::filesystem::path &filePath = "");     // Save the current requirements to a project file

  // dBus management
  using Message_ptr = std::shared_ptr<dBus::Message>;
  void         runBusListener();                                  // Run the bus listener thread
  void         stopBusListener();                                 // Stop the bus listener thread
  void         processMessageBus(const Message_ptr &message);     // Process a message received from the bus
  std::jthread m_busListenerThread;                               // Thread for listening to bus messages related to requirements

  // Events processing
  using ProjectOperationMessage_ptr = std::shared_ptr<dBus::RequestMessage<api::project::ProjectOperationEvent, void>>;
  void on_projectOperationEvent(const ProjectOperationMessage_ptr &message);      // Process a file operation event
  void on_projectCreateFileEvent(const ProjectOperationMessage_ptr &message);     // Process a file creation event
  void on_projectOpenFileEvent(const ProjectOperationMessage_ptr &message);       // Process a file opening event
  void on_projectSaveFileEvent(const ProjectOperationMessage_ptr &message);       // Process a file saving event
  void on_projectCloseFileEvent(const ProjectOperationMessage_ptr &message);      // Process a file closing event
};
//--------------------------------------------------------------
}     // namespace core::project
