#include "Logger.h"

Logger::Logger() 
    : m_logFile(nullptr)
    , m_initialized(false)
    , m_originalCallback(nullptr)
    , m_originalUserdata(nullptr)
{
}

Logger::~Logger()
{
    Close();
}

bool Logger::Init()
{
    if (m_initialized) {
        return true;
    }

    // 获取当前工作目录
    char cwd[1024];
    if (getcwd(cwd, sizeof(cwd)) == nullptr) {
        return false;
    }

    // 构建日志文件路径
    std::string logPath = std::string(cwd) + "/log.txt";
    
    // 打开日志文件（追加模式）
    m_logFile = fopen(logPath.c_str(), "a");
    if (!m_logFile) {
        return false;
    }

    // 保存原始的SDL日志回调
    SDL_LogGetOutputFunction(&m_originalCallback, &m_originalUserdata);
    
    // 设置自定义的SDL日志回调
    SDL_LogSetOutputFunction(SDLLogCallback, this);
    
    m_initialized = true;
    
    // 使用SDL_Log写入初始化信息（这会同时输出到文件和原始目标）
    SDL_Log("Logger initialized successfully - Log file: %s", logPath.c_str());
    
    return true;
}

void Logger::Close()
{
    if (m_initialized) {
        if (m_logFile) {
            SDL_Log("Logger shutting down");
            fflush(m_logFile);
            fclose(m_logFile);
            m_logFile = nullptr;
        }
        
        // 恢复原始的SDL日志回调
        if (m_originalCallback) {
            SDL_LogSetOutputFunction(m_originalCallback, m_originalUserdata);
        }
        
        m_initialized = false;
    }
}

void Logger::SDLLogCallback(void* userdata, int category, SDL_LogPriority priority, const char* message)
{
    Logger* logger = static_cast<Logger*>(userdata);
    
    // 首先调用原始回调（保持控制台输出等功能）
    if (logger->m_originalCallback) {
        logger->m_originalCallback(logger->m_originalUserdata, category, priority, message);
    }
    
    // 然后写入到日志文件
    if (logger->m_initialized && logger->m_logFile) {
        std::string timestamp = logger->GetCurrentTime();
        
        const char* priorityStr = "UNKNOWN";
        switch (priority) {
            case SDL_LOG_PRIORITY_VERBOSE: priorityStr = "VERBOSE"; break;
            case SDL_LOG_PRIORITY_DEBUG: priorityStr = "DEBUG"; break;
            case SDL_LOG_PRIORITY_INFO: priorityStr = "INFO"; break;
            case SDL_LOG_PRIORITY_WARN: priorityStr = "WARN"; break;
            case SDL_LOG_PRIORITY_ERROR: priorityStr = "ERROR"; break;
            case SDL_LOG_PRIORITY_CRITICAL: priorityStr = "CRITICAL"; break;
            default: break;
        }
        
        fprintf(logger->m_logFile, "[%s][%s] %s\n", timestamp.c_str(), priorityStr, message);
        fflush(logger->m_logFile);
    }
}

std::string Logger::GetCurrentTime()
{
    time_t rawTime;
    struct tm* timeInfo;
    char buffer[80];

    time(&rawTime);
    timeInfo = localtime(&rawTime);

    strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", timeInfo);
    return std::string(buffer);
}