#pragma once

#include <dBus/api/log.h>
#include <dBus/dBus.h>
#include <mutex>
#include <sdi_toolBox/dateTime/timer.h>
#include <thread>

namespace core::logger
{
//--------------------------------------------------------------
class Logger : public dBus::Node
{
  static constexpr auto LOG_PRINT_INTERVAL = std::chrono::milliseconds{ 500 };

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

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

  protected:
  struct
  {
    std::mutex                   mtx;         // Mutex to protect access to the log entries vector
    sdi_toolBox::dateTime::Timer timer;       // Timer to control the frequency of log printing
    std::vector<std::string>     entries;     // Vector to store log entries received from the bus
  } m_logEntries;

  private:
  void         runPrintingLoop();      // Run the loop that periodically prints log entries to the console
  void         stopPrintingLoop();     // Stop the log printing loop
  void         printLogEntries();      // Print the log entries to the console
  std::jthread m_printingThread;       // Thread for printing log entries to the console

  // Logger management
  using LogMessage_ptr = std::shared_ptr<dBus::EventMessage<api::log::LogMessage>>;
  void processUserMessage(const LogMessage_ptr &logMessage);     // Process a log message received from the bus
  void processSystemMessage(const std::string &logMessage);      // Process a system log message received from the bus

  // 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
};
//--------------------------------------------------------------
}     // namespace core::logger
