#!/usr/bin/env node
/**
 * Node.js 依赖列表更新脚本
 * 功能：对比 node_modules 中已安装的包和 dependencies.txt，如果不一致则更新 dependencies.txt
 */

const fs = require('fs');
const path = require('path');

// 获取脚本所在目录和项目根目录
const scriptDir = __dirname;
const projectRoot = path.dirname(path.dirname(scriptDir));
const dependenciesFile = path.join(scriptDir, 'dependencies.txt');
const nodeModulesPath = path.join(projectRoot, 'node_modules');

// 颜色输出函数
const colors = {
    reset: '\x1b[0m',
    red: '\x1b[31m',
    green: '\x1b[32m',
    yellow: '\x1b[33m',
    cyan: '\x1b[36m',
    white: '\x1b[37m'
};

function log(message, color = 'reset') {
    console.log(`${colors[color]}${message}${colors.reset}`);
}

/**
 * 获取 node_modules 中已安装的包列表（包含版本号）
 */
function getInstalledPackages() {
    const installedPackages = {};
    
    if (!fs.existsSync(nodeModulesPath)) {
        log('[ERROR] node_modules not found', 'red');
        return null;
    }
    
    try {
        const entries = fs.readdirSync(nodeModulesPath, { withFileTypes: true });
        
        for (const entry of entries) {
            if (entry.isDirectory()) {
                const packageName = entry.name;
                
                // 跳过特殊目录
                if (packageName.startsWith('.') || packageName === 'node_modules') {
                    continue;
                }
                
                // 处理普通包
                const packageJsonPath = path.join(nodeModulesPath, packageName, 'package.json');
                if (fs.existsSync(packageJsonPath)) {
                    try {
                        const pkg = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
                        if (pkg.name && pkg.version) {
                            installedPackages[pkg.name.toLowerCase()] = `${pkg.name}==${pkg.version}`;
                        }
                    } catch (error) {
                        // 忽略解析错误
                    }
                }
                
                // 处理 scoped 包（如 @babel/core）
                if (packageName.startsWith('@')) {
                    try {
                        const scopedPath = path.join(nodeModulesPath, packageName);
                        const scopedEntries = fs.readdirSync(scopedPath, { withFileTypes: true });
                        for (const scopedEntry of scopedEntries) {
                            if (scopedEntry.isDirectory()) {
                                const scopedPackageJsonPath = path.join(scopedPath, scopedEntry.name, 'package.json');
                                if (fs.existsSync(scopedPackageJsonPath)) {
                                    try {
                                        const pkg = JSON.parse(fs.readFileSync(scopedPackageJsonPath, 'utf-8'));
                                        if (pkg.name && pkg.version) {
                                            installedPackages[pkg.name.toLowerCase()] = `${pkg.name}==${pkg.version}`;
                                        }
                                    } catch (error) {
                                        // 忽略解析错误
                                    }
                                }
                            }
                        }
                    } catch (error) {
                        // 忽略错误
                    }
                }
            }
        }
    } catch (error) {
        log(`[ERROR] Failed to read node_modules: ${error.message}`, 'red');
        return null;
    }
    
    return installedPackages;
}

/**
 * 读取 dependencies.txt 中的包列表
 */
function readDependenciesFile() {
    if (!fs.existsSync(dependenciesFile)) {
        log(`[WARN] ${dependenciesFile} not found, will create new one`, 'yellow');
        return {};
    }
    
    const packages = {};
    try {
        const content = fs.readFileSync(dependenciesFile, 'utf-8');
        const lines = content.split('\n');
        
        for (const line of lines) {
            const trimmed = line.trim();
            if (trimmed && !trimmed.startsWith('#')) {
                // 提取包名（支持 ==, >=, <=, >, <, ~= 等版本操作符）
                if (trimmed.includes('==')) {
                    const parts = trimmed.split('==', 2);
                    packages[parts[0].trim().toLowerCase()] = trimmed;
                } else {
                    // 如果没有版本号，使用整行
                    const pkgName = trimmed.split('>=')[0].split('<=')[0].split('>')[0].split('<')[0].split('~=')[0].trim();
                    packages[pkgName.toLowerCase()] = trimmed;
                }
            }
        }
    } catch (error) {
        log(`[ERROR] Failed to read dependencies.txt: ${error.message}`, 'red');
        return {};
    }
    
    return packages;
}

/**
 * 对比并更新 dependencies.txt
 */
function compareAndUpdate() {
    log('Comparing installed packages with dependencies.txt...', 'cyan');
    log('='.repeat(60), 'cyan');
    
    // 获取已安装的包
    const installedPackages = getInstalledPackages();
    if (installedPackages === null) {
        process.exit(1);
    }
    
    // 读取 dependencies.txt 中的包
    const filePackages = readDependenciesFile();
    
    // 对比差异
    const installedSet = new Set(Object.keys(installedPackages));
    const fileSet = new Set(Object.keys(filePackages));
    
    const addedPackages = [];
    const removedPackages = [];
    const changedPackages = [];
    
    // 检查新增的包
    for (const pkgName of installedSet) {
        if (!fileSet.has(pkgName)) {
            addedPackages.push(pkgName);
        }
    }
    
    // 检查删除的包
    for (const pkgName of fileSet) {
        if (!installedSet.has(pkgName)) {
            removedPackages.push(pkgName);
        }
    }
    
    // 检查版本变化
    for (const pkgName of installedSet) {
        if (fileSet.has(pkgName)) {
            if (installedPackages[pkgName] !== filePackages[pkgName]) {
                changedPackages.push(pkgName);
            }
        }
    }
    
    // 显示差异
    if (addedPackages.length > 0) {
        log(`\n[+] Added packages (${addedPackages.length}):`, 'green');
        addedPackages.sort().forEach(pkg => {
            log(`  + ${installedPackages[pkg]}`, 'green');
        });
    }
    
    if (removedPackages.length > 0) {
        log(`\n[-] Removed packages (${removedPackages.length}):`, 'red');
        removedPackages.sort().forEach(pkg => {
            log(`  - ${filePackages[pkg]}`, 'red');
        });
    }
    
    if (changedPackages.length > 0) {
        log(`\n[~] Changed packages (${changedPackages.length}):`, 'yellow');
        changedPackages.sort().forEach(pkg => {
            log(`  ~ ${filePackages[pkg]} -> ${installedPackages[pkg]}`, 'yellow');
        });
    }
    
    // 判断是否需要更新
    if (addedPackages.length === 0 && removedPackages.length === 0 && changedPackages.length === 0) {
        log(`\n[OK] dependencies.txt is up to date`, 'green');
        log(`     Total packages: ${Object.keys(installedPackages).length}`, 'green');
        return true;
    }
    
    // 更新 dependencies.txt
    log(`\nUpdating ${dependenciesFile}...`, 'cyan');
    
    // 获取所有已安装的包（按名称排序）
    const allPackages = Object.values(installedPackages).sort();
    
    // 写入文件（UTF-8 编码）
    try {
        fs.writeFileSync(dependenciesFile, allPackages.join('\n') + '\n', 'utf-8');
        log(`[OK] ${dependenciesFile} updated successfully`, 'green');
        log(`     Total packages: ${allPackages.length}`, 'green');
        return true;
    } catch (error) {
        log(`[ERROR] Failed to write dependencies.txt: ${error.message}`, 'red');
        return false;
    }
}

/**
 * 主函数
 */
function main() {
    if (!compareAndUpdate()) {
        process.exit(1);
    }
    process.exit(0);
}

if (require.main === module) {
    main();
}
