#include "FileLogger.h"
#include <fstream>
#include <ctime>
#include <cstdio>  // 用于system()执行目录创建命令
#include <cstring> // 用于strlen（处理char*转string时的长度判断）

// -------------------------- 核心接口实现 --------------------------
void FileLogger::writeToFile(const std::string& relativePath,
                             const std::string& fileName,
                             const std::string& data,
                             WriteMode mode) {
    // 1. 拼接完整文件路径（相对路径 + 文件名）
    std::string fullPath = joinPath(relativePath, fileName);
    // 2. 自动创建目录（若路径不存在）
    createDirectory(relativePath);

    // 3. 打开文件（根据模式选择打开方式）
    std::ofstream file;
    if (mode == WriteMode::OVERWRITE) {
        // 覆盖模式：ios::trunc 清空文件，ios::out 确保可写
        file.open(fullPath, std::ios::out | std::ios::trunc);
    } else {
        // 追加模式：ios::app 从文件末尾写入，不存在则创建
        file.open(fullPath, std::ios::out | std::ios::app);
    }

    // 4. 检查文件是否成功打开
    if (!file.is_open()) {
        throw std::runtime_error("Failed to open file: " + fullPath);
    }

    // 5. 写入数据（带时间戳，便于追溯）
    file << data << std::endl;

    // 6. 关闭文件（显式关闭更安全，避免缓冲区数据丢失）
    file.close();
}

// -------------------------- 辅助函数实现 --------------------------
std::string FileLogger::joinPath(const std::string& path, const std::string& fileName) {
    if (path.empty()) {
        return fileName; // 路径为空时，直接返回文件名（当前目录）
    }
    // 检查路径末尾是否已有分隔符，避免重复（如 "log/" + "app.log" → "log/app.log"）
    if (path.back() == PATH_SEPARATOR[0]) {
        return path + fileName;
    } else {
        return path + PATH_SEPARATOR + fileName;
    }
}

void FileLogger::createDirectory(const std::string& relativePath) {
    if (relativePath.empty()) {
        return; // 无需创建当前目录
    }
    QString folderPath = QString::fromStdString(relativePath);
    QDir folder(folderPath);
    if(!folder.exists()){
        // 跨平台目录创建命令：Windows用md，Linux用mkdir
        std::string cmd;
#ifdef _WIN32
        // Windows：md /s 支持多级目录，2>nul 忽略"目录已存在"的错误提示
        cmd = "mkdir \"" + relativePath + "\" 2>nul";
#else
        // Linux/macOS：mkdir -p 支持多级目录，2>/dev/null 忽略错误提示
        cmd = "mkdir -p \"" + relativePath + "\" 2>/dev/null";
#endif

        // 执行命令：system()返回0表示成功
        int result = system(cmd.c_str());
        if (result != 0) {
            throw std::runtime_error("Failed to create directory: " + relativePath);
        }
    }
}
