/**
 * 完整反混淆脚本 - 使用多种工具清洗代码
 */
const fs = require('fs');
const path = require('path');

// 尝试导入反混淆库
let deobfuscateIO, synchrony, beautify;

try {
    deobfuscateIO = require('obfuscator-io-deobfuscator').deobfuscate;
    console.log('✓ obfuscator-io-deobfuscator 已加载');
} catch (e) {
    console.log('✗ obfuscator-io-deobfuscator 未安装');
}

try {
    synchrony = require('deobfuscator').deobfuscate;
    console.log('✓ deobfuscator (synchrony) 已加载');
} catch (e) {
    console.log('✗ deobfuscator (synchrony) 未安装');
}

try {
    beautify = require('js-beautify').js;
    console.log('✓ js-beautify 已加载');
} catch (e) {
    console.log('✗ js-beautify 未安装');
}

const inputDir = 'D:/temp/破解/cursorpro-0.4.5/原版本/extension/out';
const outputDir = 'D:/temp/破解/cursorpro-0.4.5/deobfuscated_full/extension/out';

// 确保输出目录存在
function ensureDir(dir) {
    if (!fs.existsSync(dir)) {
        fs.mkdirSync(dir, { recursive: true });
    }
}

// 使用 obfuscator-io-deobfuscator
async function deobfuscateWithIO(code, filename) {
    if (!deobfuscateIO) return null;

    try {
        console.log(`  [obfuscator-io] 处理 ${filename}...`);
        const result = deobfuscateIO(code);
        return result;
    } catch (e) {
        console.log(`  [obfuscator-io] 失败: ${e.message}`);
        return null;
    }
}

// 使用 synchrony deobfuscator
async function deobfuscateWithSynchrony(code, filename) {
    if (!synchrony) return null;

    try {
        console.log(`  [synchrony] 处理 ${filename}...`);
        const result = await synchrony(code);
        return result;
    } catch (e) {
        console.log(`  [synchrony] 失败: ${e.message}`);
        return null;
    }
}

// 美化代码
function beautifyCode(code) {
    if (!beautify) return code;

    return beautify(code, {
        indent_size: 4,
        space_in_empty_paren: true,
        preserve_newlines: true,
        max_preserve_newlines: 2,
        jslint_happy: false,
        brace_style: 'collapse',
        keep_array_indentation: false,
        keep_function_indentation: false,
        space_before_conditional: true,
        break_chained_methods: false,
        eval_code: false,
        unescape_strings: true,
        wrap_line_length: 0
    });
}

// 自定义清理：移除控制流混淆的 switch-case
function cleanControlFlow(code) {
    // 匹配 '2|5|3|4|6|1|0|7'['split']('|') 模式的控制流
    const controlFlowPattern = /const\s+_0x[a-f0-9]+\s*=\s*'[\d\|]+'(\['split'\]|\.\s*split)\s*\('\|'\);?\s*let\s+_0x[a-f0-9]+\s*=\s*0x0;?\s*while\s*\(!!\[\]\)\s*\{\s*switch\s*\(_0x[a-f0-9]+\[_0x[a-f0-9]+\+\+\]\)\s*\{/g;

    // 这个比较复杂，暂时只做标记
    let count = 0;
    code = code.replace(controlFlowPattern, (match) => {
        count++;
        return `/* [CONTROL_FLOW_${count}] */ ${match}`;
    });

    if (count > 0) {
        console.log(`  发现 ${count} 处控制流混淆`);
    }

    return code;
}

// 清理对象属性访问
function cleanPropertyAccess(code) {
    // 将 obj['property'] 转换为 obj.property (对于合法标识符)
    const validIdentifier = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/;

    code = code.replace(/\['([a-zA-Z_$][a-zA-Z0-9_$]*)'\]/g, (match, prop) => {
        if (validIdentifier.test(prop)) {
            return `.${prop}`;
        }
        return match;
    });

    return code;
}

// 处理单个文件
async function processFile(inputPath, outputPath, filename) {
    console.log(`\n处理: ${filename}`);

    let code = fs.readFileSync(inputPath, 'utf8');
    console.log(`  原始大小: ${(code.length / 1024).toFixed(2)} KB`);

    let result = null;

    // 方法1: 尝试 obfuscator-io-deobfuscator
    result = await deobfuscateWithIO(code, filename);

    // 方法2: 如果失败，尝试 synchrony
    if (!result) {
        result = await deobfuscateWithSynchrony(code, filename);
    }

    // 如果两个库都失败，使用原始代码
    if (!result) {
        console.log(`  使用原始代码（反混淆库失败）`);
        result = code;
    }

    // 自定义清理
    result = cleanPropertyAccess(result);
    result = cleanControlFlow(result);

    // 美化
    result = beautifyCode(result);

    console.log(`  处理后大小: ${(result.length / 1024).toFixed(2)} KB`);

    // 保存
    ensureDir(path.dirname(outputPath));
    fs.writeFileSync(outputPath, result);
    console.log(`  ✓ 已保存: ${outputPath}`);

    return result;
}

// 主函数
async function main() {
    console.log('========================================');
    console.log('     完整反混淆脚本');
    console.log('========================================\n');

    const files = [
        { input: 'extension.js', output: 'extension.js' },
        { input: 'webview/provider.js', output: 'webview/provider.js' },
        { input: 'utils/account.js', output: 'utils/account.js' },
        { input: 'utils/sqlite.js', output: 'utils/sqlite.js' },
    ];

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

        if (fs.existsSync(inputPath)) {
            await processFile(inputPath, outputPath, file.input);
        } else {
            console.log(`\n跳过: ${file.input} (文件不存在)`);
        }
    }

    console.log('\n========================================');
    console.log('     完成！');
    console.log('========================================');
    console.log(`输出目录: ${outputDir}`);
}

main().catch(console.error);
