// logger.cpp
#include "logger.hpp"
#include <iomanip>
#include <ctime>
#include <fstream>
#include <cstdio>

std::ofstream Logger::log_file;
std::string Logger::current_log_filename;

void Logger::set_log_to_file(const std::string &filename)
{
    current_log_filename = filename;
    log_file.open(filename, std::ios::app);
    if (!log_file.is_open())
    {
        std::cerr << "[Logger] Failed to open log file: " << filename << std::endl;
    }
}

std::string Logger::get_time_string()
{
    auto now = std::chrono::system_clock::now();
    auto millis = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()) % 1000;
    std::time_t t = std::chrono::system_clock::to_time_t(now + std::chrono::hours(8)); // UTC+8
    std::tm tm_now = *std::localtime(&t);

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

std::string Logger::get_current_time_utc8()
{
    using namespace std::chrono;

    auto now = system_clock::now();
    now += hours(8); // UTC+8

    std::time_t t = system_clock::to_time_t(now);
    auto millis = duration_cast<milliseconds>(now.time_since_epoch()) % 1000;

    std::tm tm_now = *std::localtime(&t);

    std::ostringstream ss;
    ss << std::put_time(&tm_now, "%Y%m%d%H%M%S")
       << std::setw(3) << std::setfill('0') << millis.count();

    return ss.str();
}

void Logger::log(LogLevel level, const std::string &msg)
{
    std::string level_str;
    switch (level)
    {
    case LogLevel::INFO:
        level_str = "[INFO] ";
        break;
    case LogLevel::WARN:
        level_str = "[WARN] ";
        break;
    case LogLevel::ERROR:
        level_str = "[ERROR]";
        break;
    }

    std::string full_msg = get_time_string() + " " + level_str + " " + msg;

    std::cout << full_msg << std::endl;

    if (log_file.is_open())
    {
        log_file << full_msg << std::endl;
        log_file.flush();

        // 检查是否需要轮转
        if (get_file_size(current_log_filename) >= MAX_LOG_FILE_SIZE)
        {
            rotate_logs();
        }
    }
}

size_t Logger::get_file_size(const std::string &filename)
{
    std::ifstream in(filename, std::ifstream::ate | std::ifstream::binary);
    return in.is_open() ? static_cast<size_t>(in.tellg()) : 0;
}

void Logger::rotate_logs()
{
    log_file.close();

    // 删除最旧的日志
    std::string oldest = current_log_filename + "." + std::to_string(MAX_LOG_BACKUP_COUNT);
    std::remove(oldest.c_str());

    // 重命名 *.4 -> *.5, ..., *.1 -> *.2
    for (int i = MAX_LOG_BACKUP_COUNT - 1; i >= 1; --i)
    {
        std::string old_name = current_log_filename + "." + std::to_string(i);
        std::string new_name = current_log_filename + "." + std::to_string(i + 1);
        std::rename(old_name.c_str(), new_name.c_str());
    }

    // 当前日志 -> .1
    std::string first_backup = current_log_filename + ".1";
    std::rename(current_log_filename.c_str(), first_backup.c_str());

    // 重新打开新日志
    log_file.open(current_log_filename, std::ios::trunc);
}
