import fs from "fs";
import path from "path";
import {spawn} from "child_process";
import {fileURLToPath, pathToFileURL} from "url";

// 获取 pluginManager.js 的目录
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

// plugin.js 和 plugin.example.js 在上级目录
const userConfigPath = path.join(__dirname, "../plugin.js");
const exampleConfigPath = path.join(__dirname, "../plugin.example.js");

// 尝试加载用户配置，如果没有就用 example
let plugins = [];
try {
    console.log(`检查插件配置文件: ${userConfigPath} 是否存在`);
    if (fs.existsSync(userConfigPath)) {
        plugins = (await import(pathToFileURL(userConfigPath).href)).default;
        console.log("[pluginManager] 使用用户 plugin.js 配置");
    } else if (fs.existsSync(exampleConfigPath)) {
        plugins = (await import(pathToFileURL(exampleConfigPath).href)).default;
        console.log("[pluginManager] 使用默认 plugin.example.js 配置");
    }
} catch (err) {
    console.error("[pluginManager] 加载插件配置失败:", err);
    plugins = [];
}

/**
 * 获取插件对应的二进制文件路径
 * @param {string} rootDir 项目根目录
 * @param {string} pluginPath 插件目录路径 (例: plugins/req-proxy)
 * @param {string} pluginName 插件名 (例: req-proxy)
 */
function getPluginBinary(rootDir, pluginPath, pluginName) {
    const platform = process.platform;
    const binDir = path.join(rootDir, pluginPath);

    let binaryName = null;
    if (platform === "win32") {
        binaryName = `${pluginName}-windows.exe`;
    } else if (platform === "linux") {
        binaryName = `${pluginName}-linux`;
    } else if (platform === "darwin") {
        binaryName = `${pluginName}-darwin`;
    } else if (platform === "android") {
        binaryName = `${pluginName}-android`;
    } else {
        console.log("[getPluginBinary] Unsupported platform: " + platform);
        return null;
    }

    return path.join(binDir, binaryName);
}

function ensureExecutable(filePath) {
    if (process.platform === "win32") {
        // Windows 不需要 chmod，直接返回
        return;
    }
    try {
        const stats = fs.statSync(filePath);
        if (!(stats.mode & 0o111)) {
            fs.chmodSync(filePath, 0o755);
            console.log(`[pluginManager] 已为插件 ${filePath} 添加执行权限`);
        }
    } catch (err) {
        console.error(`[pluginManager] 无法设置执行权限: ${filePath}`, err.message);
    }
}

/**
 * 启动插件
 * @param {Object} plugin 插件配置
 * @param {string} rootDir 项目根目录
 */
function startPlugin(plugin, rootDir) {
    if (!plugin.active) {
        console.log(`[pluginManager] 插件 ${plugin.name} 未激活，跳过`);
        return null;
    }

    const binary = getPluginBinary(rootDir, plugin.path, plugin.name);
    if (!binary || !fs.existsSync(binary)) {
        console.error(`[pluginManager] 插件 ${plugin.name} 的二进制文件不存在: ${binary}`);
        return null;
    }

    console.log(`[pluginManager] 启动插件 ${plugin.name}: ${binary} ${plugin.params || ""}`);

    const args = plugin.params ? plugin.params.split(" ") : [];
    let proc;

    try {
        ensureExecutable(binary);
        // 用 pipe 方式，便于我们捕获插件日志
        proc = spawn(binary, args, {stdio: ["ignore", "pipe", "pipe"]});

        // 检查是否真的启动了
        if (!proc || !proc.pid) {
            console.error(`[pluginManager] 插件 ${plugin.name} 启动失败 (无效的进程 PID)`);
            return null;
        }

        proc.stdout.on("data", (data) => {
            console.log(`[${plugin.name}]`, data.toString().trim());
        });

        proc.stderr.on("data", (data) => {
            console.log(`[${plugin.name}-STD]`, data.toString().trim());
        });

        proc.on("error", (err) => {
            if (err.code === "EACCES") {
                console.error(`[pluginManager] 插件 ${plugin.name} 无法执行: 没有执行权限，请运行: chmod +x ${binary}`);
            } else if (err.code === "ENOENT") {
                console.error(`[pluginManager] 插件 ${plugin.name} 启动失败: 找不到可执行文件 ${binary}`);
            } else {
                console.error(`[pluginManager] 插件 ${plugin.name} 运行中出错:`, err.message);
            }
            // 标记为“启动失败”，避免 exit 再重复打印
            proc._failedToSpawn = true;
        });

        proc.on("exit", (code, signal) => {
            if (proc._failedToSpawn) return; // 忽略 spawn 失败导致的 exit
            console.log(`[pluginManager] 插件 ${plugin.name} 退出 (code=${code}, signal=${signal})`);
        });

        return proc;
    } catch (err) {
        console.error(`[pluginManager] 插件 ${plugin.name} 启动失败 (spawn 出错):`, err.message);
        return null;
    }
}

/**
 * 启动所有插件
 * @param {string} rootDir 项目根目录
 */
export function startAllPlugins(rootDir = process.cwd()) {
    console.log("[pluginManager] 准备启动所有插件...");
    const processes = {};
    for (const plugin of plugins) {
        const proc = startPlugin(plugin, rootDir);
        if (proc) {
            processes[plugin.name] = proc;
        } else {
            console.error(`[pluginManager] 插件 ${plugin.name} 启动失败，未加入到 processes`);
        }
    }
    return processes;
}
