#include "tlogger.h"

#include <iomanip>
#include <iostream>

namespace TC {
// ConsoleOutput实现
void ConsoleOutput::write(LogLevel level, const std::string& message)
{
    std::ostream& stream = (level >= LogLevel::WARNING) ? std::cerr : std::cout;
    stream << message << std::endl;
    stream.flush();
}

// FileOutput实现
FileOutput::FileOutput(const std::string& filename)
{
    m_file.open(filename, std::ios::app);
    if (!m_file.is_open()) {
        std::cerr << "Failed to open log file: " << filename << std::endl;
    }
}

FileOutput::~FileOutput()
{
    if (m_file.is_open()) {
        m_file.close();
    }
}

void FileOutput::write(LogLevel level, const std::string& message)
{
    std::lock_guard<std::mutex> lock(m_mutex);
    if (m_file.is_open()) {
        m_file << message << std::endl;
        m_file.flush();
    }
}

// Logger实现
Logger& Logger::instance()
{
    static Logger instance;
    return instance;
}

void Logger::setLevel(LogLevel level)
{
    std::lock_guard<std::mutex> lock(m_mutex);
    m_level = level;
}

LogLevel Logger::getLevel() const
{
    std::lock_guard<std::mutex> lock(m_mutex);
    return m_level;
}

void Logger::addOutput(std::unique_ptr<LogOutput> output)
{
    std::lock_guard<std::mutex> lock(m_mutex);
    m_outputs.push_back(std::move(output));
}

void Logger::clearOutputs()
{
    std::lock_guard<std::mutex> lock(m_mutex);
    m_outputs.clear();
}

void Logger::debug(const std::string& message)
{
    if (shouldLog(LogLevel::DEBUG)) {
        log(LogLevel::DEBUG, message);
    }
}

void Logger::info(const std::string& message)
{
    if (shouldLog(LogLevel::INFO)) {
        log(LogLevel::INFO, message);
    }
}

void Logger::warning(const std::string& message)
{
    if (shouldLog(LogLevel::WARNING)) {
        log(LogLevel::WARNING, message);
    }
}

void Logger::error(const std::string& message)
{
    if (shouldLog(LogLevel::ERROR)) {
        log(LogLevel::ERROR, message);
    }
}

void Logger::initialize(const std::string& logFile,
                        LogLevel level,
                        bool enableConsole,
                        bool enableQt)
{
    Logger& logger = instance();
    logger.clearOutputs();
    logger.setLevel(level);

    // 添加文件输出
    if (!logFile.empty()) {
        logger.addOutput(std::make_unique<FileOutput>(logFile));
    }

    // 添加控制台输出
    if (enableConsole) {
        logger.addOutput(std::make_unique<ConsoleOutput>());
    }

    logger.info("AV Logger initialized");
}

void Logger::log(LogLevel level, const std::string& message)
{
    std::lock_guard<std::mutex> lock(m_mutex);

    std::string formattedMessage = getCurrentTime() + " [" + levelToString(level) + "] " + message;

    for (auto& output : m_outputs) {
        if (output) {
            output->write(level, formattedMessage);
        }
    }
}

bool Logger::shouldLog(LogLevel level) const
{
    return level >= m_level;
}

std::string Logger::getCurrentTime() const
{
    auto now = std::chrono::system_clock::now();
    auto time_t = std::chrono::system_clock::to_time_t(now);
    auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()) % 1000;

    std::ostringstream oss;
    oss << std::put_time(std::localtime(&time_t), "%Y-%m-%d %H:%M:%S");
    oss << '.' << std::setfill('0') << std::setw(3) << ms.count();
    return oss.str();
}

std::string Logger::levelToString(LogLevel level) const
{
    switch (level) {
    case LogLevel::DEBUG:
        return "DEBUG";
    case LogLevel::INFO:
        return "INFO";
    case LogLevel::WARNING:
        return "WARN";
    case LogLevel::ERROR:
        return "ERROR";
    default:
        return "UNKNOWN";
    }
}
} // namespace TC
