import { existsSync, mkdirSync, rmSync, cpSync, symlinkSync, lstatSync, realpathSync } from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import { getRuntimeHomeDir } from '../config.js';
import { logger } from '../utils/logger.js';
function getBridgePackageRoot() {
    const currentFile = fileURLToPath(import.meta.url);
    return path.resolve(path.dirname(currentFile), '..', '..');
}
function getBundledAcodeRoot(packageRoot = getBridgePackageRoot()) {
    return path.join(packageRoot, 'package', 'acode');
}
function getReleasedAcodeRoot() {
    return path.join(getRuntimeHomeDir(), '.agentswork', 'runtime-bridge', 'packages', 'acode');
}
function shouldReplaceNodeModulesLink(targetPath) {
    if (!existsSync(targetPath)) {
        return true;
    }
    const stat = lstatSync(targetPath);
    return stat.isSymbolicLink() || stat.isDirectory();
}
function isExpectedNodeModulesLink(targetPath, sourcePath) {
    if (!existsSync(targetPath)) {
        return false;
    }
    try {
        return realpathSync(targetPath) === realpathSync(sourcePath);
    }
    catch {
        return false;
    }
}
function ensureReleasedNodeModules(packageRoot, releasedRoot) {
    const sourceNodeModules = path.join(packageRoot, 'node_modules');
    const releasedNodeModules = path.join(releasedRoot, 'node_modules');
    if (!existsSync(sourceNodeModules)) {
        logger.warn(`[runtime-bridge] ACode 未找到 bridge node_modules，依赖解析可能失败: ${sourceNodeModules}`);
        return;
    }
    if (isExpectedNodeModulesLink(releasedNodeModules, sourceNodeModules)) {
        return;
    }
    if (!shouldReplaceNodeModulesLink(releasedNodeModules)) {
        logger.warn(`[runtime-bridge] ACode node_modules 路径已存在但不是目录或链接，已保留: ${releasedNodeModules}`);
        return;
    }
    rmSync(releasedNodeModules, { recursive: true, force: true });
    symlinkSync(sourceNodeModules, releasedNodeModules, process.platform === 'win32' ? 'junction' : 'dir');
}
export function getReleasedAcodeEntryPath() {
    return path.join(getReleasedAcodeRoot(), 'dist', 'index.js');
}
/**
 * 释放随 bridge 打包的内置 ACode runtime。
 * 主流程：检查 bundled dist -> 复制 dist 与 metadata -> 链接 bridge node_modules，
 * 确保 ACode 无需安装即可被 Adapter 动态加载。
 */
export function ensureAcodePackageReleased() {
    const packageRoot = getBridgePackageRoot();
    const bundledRoot = getBundledAcodeRoot(packageRoot);
    const bundledDist = path.join(bundledRoot, 'dist');
    const bundledEntry = path.join(bundledDist, 'index.js');
    if (!existsSync(bundledEntry)) {
        logger.warn(`[runtime-bridge] 未找到 bundled ACode dist，ACode 启动可能失败: ${bundledEntry}`);
        return null;
    }
    const releasedRoot = getReleasedAcodeRoot();
    const releasedDist = path.join(releasedRoot, 'dist');
    mkdirSync(releasedRoot, { recursive: true });
    rmSync(releasedDist, { recursive: true, force: true });
    cpSync(bundledDist, releasedDist, { recursive: true, force: true, errorOnExist: false });
    for (const fileName of ['package.json', 'README.md']) {
        const source = path.join(bundledRoot, fileName);
        if (existsSync(source)) {
            cpSync(source, path.join(releasedRoot, fileName), { force: true, errorOnExist: false });
        }
    }
    ensureReleasedNodeModules(packageRoot, releasedRoot);
    logger.info(`[runtime-bridge] ACode 已准备: ${getReleasedAcodeEntryPath()}`);
    return getReleasedAcodeEntryPath();
}
