import fs from 'fs';
import path from 'path';
import xxtea from 'xxtea-node';
import pako from 'pako';
import FileUtils from '../utils/FileUtils';

const SCRIPT_PACKAGE = fs.readFileSync(path.join(__dirname, '..', 'template', 'SCRIPT_PACKAGE.js')).toString();
// const SCRIPT_PACKAGE_ISOLATE = fs.readFileSync(path.join(__dirname, '..', 'template', 'SCRIPT_PACKAGE_ISOLATE.js')).toString();

const SETTING_GOURPLIST_REGEXP = /groupList:\s*(\[['",a-zA-Z0-9\s]+])/mg
const SETTING_COLLISIONMATRIX_REGEXP = /collisionMatrix:\s*(\[[\[\],truefalse\s]+\])/mg

export function PackageScript(key: string, buildPath: string, isolate: boolean = false, xxtea?: string, ungzip: boolean = false): void {
    const bundleDir = path.join(buildPath, 'assets', key);
    if (fs.existsSync(path.join(bundleDir, 'config.subgame.json'))) {
        console.warn(`Package [${key}] script packaged`)
        return;
    }

    console.log(`Package [${key}] find config`);
    const configPath = FileUtils.find(bundleDir, /config\.([a-zA-Z0-9\.]+\.)?json/);
    fs.renameSync(configPath, path.join(bundleDir, 'config.subgame.json'));
    console.log(`Package [${key}] config finded, renames`);




    console.log(`Package [${key}] find index script`);
    const scriptPath = FileUtils.find(bundleDir, /index\.([a-zA-Z0-9\.]+\.)?js/);
    const scriptEncrypt = path.extname(scriptPath) === '.jsc';
    let scriptBuffer = fs.readFileSync(scriptPath);
    let script: string
    if (scriptEncrypt) {
        script = decryptJSC(scriptBuffer, xxtea, ungzip);
        console.log(`Package [${key}] index script decrypt result: ${script.substring(0, 100)}...`);//输出Script，判断解密结果
    } else {
        script = scriptBuffer.toString();
    }

    if (isolate) {

        console.log(`Package [${key}] find settings`);
        const settingPath = FileUtils.find(path.join(buildPath, 'src'), /settings\.([a-zA-Z0-9\.]+\.)?js/);
        const settingsBuffer = fs.readFileSync(settingPath);
        let settings: string;
        if (path.extname(settingPath) === '.jsc') {
            settings = decryptJSC(settingsBuffer, xxtea, ungzip);
            console.log(`Package [${key}] settings script decrypt result: ${settings.substring(0, 100)}...`);//输出Script，判断解密结果
        }
        else settings = settingsBuffer.toString();
        const groupList = SETTING_GOURPLIST_REGEXP.exec(settings)[1];
        const collisionMatrix = SETTING_COLLISIONMATRIX_REGEXP.exec(settings)[1];
        console.log(`Package [${key}] settings finded, saved`);

        script = SCRIPT_PACKAGE
            .replace('"%{subgame_key}"', key)
            .replace('"%{subgame_content}"', script)
            .replace('"%{subgame_group_list}"', groupList)
            .replace('"%{subgame_collision_matrix}"', collisionMatrix);

        console.log(`Package [${key}] class isolate`);
    }
    if (scriptEncrypt) fs.writeFileSync(scriptPath, encryptJS(script, xxtea, ungzip));
    else fs.writeFileSync(scriptPath, script);
    fs.renameSync(scriptPath, path.join(bundleDir, 'index.subgame' + path.extname(scriptPath)));
    console.log(`Package [${key}] index script packaged`);
}

 const decryptJSC = (data: Buffer, key: string, ungzip: boolean = true): string => {
    let res: Uint8Array = xxtea.decrypt(data, xxtea.toBytes(key))
    res = pako.ungzip(res)
    return xxtea.toString(res);
}

 const encryptJS = (data: string, key: string, ungzip: boolean = true): Uint8Array => {
    const res: Uint8Array = pako.gzip(xxtea.toBytes(data), { level: 6 })
    const result = xxtea.encrypt(res, xxtea.toBytes(key));
    console.dir(result);
    return result;
}
