/**
 * 批量生成解码映射 - 为每个混淆文件生成 decoded_map.json
 */
const fs = require('fs');
const path = require('path');
const vm = require('vm');

const baseDir = 'D:/temp/破解/cursorpro-0.4.5';

/**
 * 从代码中提取解码器并生成映射
 */
function generateDecodeMap(code, filename) {
    console.log(`\n处理: ${filename}`);
    console.log('='.repeat(40));

    // 查找字符串数组函数
    const arrayFuncMatch = code.match(/function\s+(_0x[a-f0-9]+)\s*\(\)\s*\{/);
    if (!arrayFuncMatch) {
        console.log('  未找到字符串数组函数');
        return null;
    }
    const arrayFuncName = arrayFuncMatch[1];

    // 查找解码函数
    const decoderMatch = code.match(/function\s+(_0x[a-f0-9]+)\s*\(\s*_0x[a-f0-9]+\s*,\s*_0x[a-f0-9]+\s*\)\s*\{/);
    if (!decoderMatch) {
        console.log('  未找到解码函数');
        return null;
    }
    const decoderFuncName = decoderMatch[1];

    console.log(`  数组函数: ${arrayFuncName}`);
    console.log(`  解码函数: ${decoderFuncName}`);

    // 提取所有解码器调用模式
    const callPatterns = [
        /_0x[a-f0-9]+\s*\(\s*(0x[a-f0-9]+)\s*,\s*'([^']*)'\s*\)/g,
        /_0x[a-f0-9]+\s*\(\s*(0x[a-f0-9]+)\s*,\s*"([^"]*)"\s*\)/g
    ];

    const calls = new Set();
    for (const pattern of callPatterns) {
        let match;
        while ((match = pattern.exec(code)) !== null) {
            calls.add(match[0]);
        }
    }

    console.log(`  找到 ${calls.size} 个唯一调用`);

    // 尝试设置沙盒执行解码器
    // 提取从开头到第一个 exports 之前的所有代码
    let exportIndex = code.indexOf('Object.defineProperty(exports');
    if (exportIndex === -1) {
        exportIndex = code.indexOf('exports.');
    }
    if (exportIndex === -1) {
        exportIndex = code.length;
    }

    // 找到解码函数结束位置
    const decoderStart = code.indexOf(`function ${decoderFuncName}(`);
    let braceCount = 0, decoderEnd = decoderStart, foundStart = false;
    for (let i = decoderStart; i < code.length; i++) {
        if (code[i] === '{') { braceCount++; foundStart = true; }
        else if (code[i] === '}') {
            braceCount--;
            if (foundStart && braceCount === 0) {
                decoderEnd = i + 1;
                break;
            }
        }
    }

    // 提取设置代码
    const setupCode = code.substring(0, Math.min(decoderEnd + 500, exportIndex));

    // 在沙盒中执行
    const sandbox = {
        console: { log: () => {}, warn: () => {}, error: () => {} },
        parseInt,
        String,
        decodeURIComponent,
        vip: 'cursor'
    };

    try {
        vm.runInNewContext(setupCode, sandbox);

        // 测试解码器
        const testResult = vm.runInNewContext(`typeof ${decoderFuncName}`, sandbox);
        if (testResult !== 'function') {
            console.log(`  解码器不可用: ${testResult}`);
            return null;
        }
        console.log(`  解码器设置成功`);

        // 解码所有调用
        const decodeMap = {};
        let successCount = 0;
        let failCount = 0;

        for (const call of calls) {
            // 提取参数
            const paramMatch = call.match(/_0x[a-f0-9]+\s*\(\s*(0x[a-f0-9]+)\s*,\s*['"]([^'"]*)['"]\s*\)/);
            if (!paramMatch) continue;

            const num = paramMatch[1];
            const key = paramMatch[2];

            try {
                const decoded = vm.runInNewContext(
                    `${decoderFuncName}(${num},'${key.replace(/'/g, "\\'")}')`,
                    sandbox
                );
                if (typeof decoded === 'string') {
                    decodeMap[call] = decoded;
                    successCount++;
                } else {
                    failCount++;
                }
            } catch (e) {
                failCount++;
            }
        }

        console.log(`  成功解码: ${successCount}`);
        console.log(`  解码失败: ${failCount}`);

        return decodeMap;
    } catch (e) {
        console.log(`  沙盒执行失败: ${e.message}`);
        return null;
    }
}

// 主函数
function main() {
    console.log('╔════════════════════════════════════════╗');
    console.log('║     批量生成解码映射                     ║');
    console.log('╚════════════════════════════════════════╝');

    const files = [
        { input: '原版本/extension/out/webview/provider.js', output: 'provider_decoded_map.json' },
        { input: '原版本/extension/out/extension.js', output: 'extension_decoded_map.json' },
        { input: '原版本/extension/out/utils/account.js', output: 'account_decoded_map.json' },
        { input: '原版本/extension/out/utils/sqlite.js', output: 'sqlite_decoded_map.json' },
        { input: '原版本/extension/out/api/client.js', output: 'client_decoded_map.json' }
    ];

    for (const file of files) {
        const inputPath = path.join(baseDir, file.input);
        const outputPath = path.join(baseDir, file.output);

        // 检查是否已存在
        if (fs.existsSync(outputPath)) {
            const existing = JSON.parse(fs.readFileSync(outputPath, 'utf8'));
            console.log(`\n${file.output}: 已存在 (${Object.keys(existing).length} 条)`);
            continue;
        }

        if (!fs.existsSync(inputPath)) {
            console.log(`\n跳过: ${file.input} (不存在)`);
            continue;
        }

        const code = fs.readFileSync(inputPath, 'utf8');
        const decodeMap = generateDecodeMap(code, file.input);

        if (decodeMap && Object.keys(decodeMap).length > 0) {
            fs.writeFileSync(outputPath, JSON.stringify(decodeMap, null, 2));
            console.log(`  已保存: ${outputPath}`);
        } else {
            console.log(`  无法生成映射`);
        }
    }

    console.log('\n完成！');
}

main();
