#ifndef LOGGER_H
#define LOGGER_H

#include <string>
#include <fstream>
#include <mutex>
#include <memory>
#include <sstream>
#include <chrono>
#include <iomanip>

/**
 * @brief Log level enumeration
 */
enum class LogLevel {
    DEBUG,
    INFO,
    WARNING,
    ERROR
};

/**
 * @brief Simple logger with file and console output support
 *
 * Designed to be systemd-friendly with structured logging format
 */
class Logger {
public:
    /**
     * @brief Get the singleton logger instance
     */
    static Logger& getInstance();

    /**
     * @brief Initialize the logger
     *
     * @param enableFileLogging Enable logging to file
     * @param logFilePath Path to log file (if file logging enabled)
     * @param minLevel Minimum log level to output
     */
    void initialize(bool enableFileLogging = false,
                   const std::string& logFilePath = "",
                   LogLevel minLevel = LogLevel::INFO);

    /**
     * @brief Log a message
     *
     * @param level Log level
     * @param message Message to log
     */
    void log(LogLevel level, const std::string& message);

    /**
     * @brief Log debug message
     */
    void debug(const std::string& message) { log(LogLevel::DEBUG, message); }

    /**
     * @brief Log info message
     */
    void info(const std::string& message) { log(LogLevel::INFO, message); }

    /**
     * @brief Log warning message
     */
    void warning(const std::string& message) { log(LogLevel::WARNING, message); }

    /**
     * @brief Log error message
     */
    void error(const std::string& message) { log(LogLevel::ERROR, message); }

    /**
     * @brief Check if file logging is enabled
     */
    bool isFileLoggingEnabled() const { return m_fileLoggingEnabled; }

    /**
     * @brief Get current log file path
     */
    std::string getLogFilePath() const { return m_logFilePath; }

    /**
     * @brief Close log file
     */
    void close();

private:
    Logger() = default;
    ~Logger();

    // Prevent copying
    Logger(const Logger&) = delete;
    Logger& operator=(const Logger&) = delete;

    std::string getCurrentTimestamp();
    std::string levelToString(LogLevel level);
    std::string levelToSystemdPriority(LogLevel level);

    bool m_fileLoggingEnabled = false;
    std::string m_logFilePath;
    LogLevel m_minLevel = LogLevel::INFO;
    std::ofstream m_logFile;
    mutable std::mutex m_mutex;
};

// Convenience macros for logging
#define LOG_DEBUG(msg) Logger::getInstance().debug(msg)
#define LOG_INFO(msg) Logger::getInstance().info(msg)
#define LOG_WARNING(msg) Logger::getInstance().warning(msg)
#define LOG_ERROR(msg) Logger::getInstance().error(msg)

#endif // LOGGER_H
