
import fs from 'fs';
import path from 'path'
import FeishuHandler from './build/handler/FeishuHandler';
import Handler from './build/handler/Handler';
import WechatHandler from './build/handler/WechatHandler';
import PackageAndroid, { Result } from './package/PackagerAndroid';
import PackageWeb from './package/PackagerWeb';
import FileUtils from './utils/FileUtils';
import MD5Utils from './utils/MD5Utils';
import ProcessUtils from './utils/ProcessUtils';
(async () => {


    const command = ProcessUtils.getArg('--run', value => ['package', 'begin', 'end', 'cache'].indexOf(value) >= 0);
    if (!command) {
        console.error(`command error: ${command}`);
        return;
    }

    if (command === 'cache') {
        const url = ProcessUtils.getArg('--url', value => !!value && value.startsWith('http'));
        if (!url) {
            console.error(`illegal parameter --url`);
            return;
        }
        const configCache = path.join(process.env.HOME || process.env.USERPROFILE, '.sgp', 'config', `${MD5Utils.md5(url)}.json`);
        console.log(`config cache: ${configCache}`);
        return;
    }

    const project = ProcessUtils.getArg('--project', fs.existsSync);
    if (!project) {
        console.error(`illegal parameter --project or file not exists`);
        return;
    }
    const platform = ProcessUtils.getArg('--platform', value => ['web-mobile', 'android'].indexOf(value) >= 0);
    if (!project) {
        console.error(`illegal parameter --platform`);
        return;
    }

    const isolate = ProcessUtils.haveArg('--isolate');
    const mode = ProcessUtils.getArg('--mode', value => ['dev', 'debug', 'release', 'testRelease'].indexOf(value) >= 0);

    const buildResultCacheFile = path.join(project, `build_result_${mode}.json`);


    switch (command) {
        case 'begin':
        case 'end':
            {
                const key = ProcessUtils.getArg('--key', value => !!value && !value.startsWith('--'));
                const robotKey = ProcessUtils.getArg('--robot-key', value => value && !value.startsWith('--'));
                if (!robotKey) {
                    console.error(`illegal parameter --robot-key`);
                    break;
                }
                const robotType = ProcessUtils.getArg('--robot-type', value => ['wechat', 'feishu'].indexOf(value.toLocaleLowerCase()) >= 0);
                if (!robotType) {
                    console.error(`illegal parameter --robot-type`);
                    break;
                }

                const data: string[] = [];
                data.push(`平台=${platform}`);
                mode && data.push(`环境=${mode}`);
                data.push(`引擎隔离=${isolate ? '开启' : '关闭'}`);
                if (fs.existsSync(buildResultCacheFile)) {
                    if (command === 'end') {
                        const cacheContent = fs.readFileSync(buildResultCacheFile).toString();
                        console.log(`Cache Content: ${cacheContent}`);
                        const buildResult = JSON.parse(cacheContent);
                        if (buildResult.backupTimestamp) data.push(`构建备份=${buildResult.backupTimestamp}`)
                        const results: Result[] = buildResult.results;
                        results.forEach(result => {
                            results.length > 1 && data.push(`**SubGame - ${result.key}**`);
                            data.push(`框架版本=${result.frameworkVersion}`);
                            data.push(`游戏版本=${result.packageVersion}`);
                            data.push(`新增文件=${result.added}`);
                            data.push(`修改文件=${result.changed}`);
                            data.push(`删除文件=${result.deleted}`);
                            if (result.size >= 0) {
                                data.push(`游戏包大小=${(result.size / 1024 / 1024).toFixed(2)}MB`)
                                if (result.supportVersion && result.supportVersion.length) {
                                    if (result.supportVersion.length === 1)
                                        data.push(`增量支持版本=${result.supportVersion.shift()}`);
                                    else
                                        data.push(`增量支持版本=${result.supportVersion.shift()} - ${result.supportVersion.pop()}`);
                                }
                            } else {
                                data.push(`没有需要构建的更新`)
                            }
                        });

                    }
                    FileUtils.rm(buildResultCacheFile);
                }

                const customData = ProcessUtils.getArg('--data', value => value && !value.startsWith('--'));
                customData && data.unshift(...customData.split(';'));

                const handler: Handler = new (robotType === 'wechat' ? WechatHandler : FeishuHandler)(robotKey, key ? `SubGame - ${key}` : `SubGame In Project`, project, data.join(';'));
                command === 'begin' ? await handler.begin() : await handler.end();
            }
            break;
        case 'package':
            {


                const outputDir = path.join(project, 'build', 'subgame', platform);
                FileUtils.rm(outputDir);

                const buildPath = path.join(project, 'build', platform === 'android' ? 'jsb-default' : platform, 'assets');
                const packageAll = ProcessUtils.haveArg('--all');
                const keys: string[] = [];


                if (packageAll) {
                    const subGameDir = fs.readdirSync(buildPath);
                    subGameDir.forEach(dir => {
                        if (dir === 'main' || dir === 'internal' || dir === 'resources' || dir.startsWith('_')) return;
                        const stat = fs.statSync(path.join(buildPath, dir));
                        if (stat.isFile()) return;
                        keys.push(dir);
                    })
                } else {
                    const key = ProcessUtils.getArg('--key', value => fs.existsSync(path.join(buildPath, value)));
                    if (!key) {
                        console.error(`illegal parameter --key or file not exists`);
                        break;
                    }
                    keys.push(key);
                }


                switch (platform) {
                    case 'android':
                        {
                            if (!mode) {
                                console.error(`illegal parameter --mode`);
                                break;
                            }


                            const xxtea = ProcessUtils.getArg('--xxtea', value => !!value && !value.startsWith('--')) || '';
                            const zipCompressJs = !!ProcessUtils.haveArg('--zipCompressJs');
                            const url = ProcessUtils.getArg('--url', value => !!value && value.startsWith('http'));
                            const codeVersion = fs.readFileSync(path.join(project, 'sg_ver.txt')).toString();
                            const results: Result[] = []
                            for (const key of keys) {
                                const result = await PackageAndroid(project, key, codeVersion, mode, url, xxtea, zipCompressJs, isolate);
                                result && results.push(result);
                            }

                            const buildResult: any = { results }

                            const backup = ProcessUtils.haveArg('--backup');
                            if (backup) {
                                const dateDir = (new Date()).toLocaleString().replace(/[\/\\:]/gm, '-');
                                buildResult.backupTimestamp = dateDir;
                                const backupDir = path.join(project, '.subgame_bak', dateDir);
                                FileUtils.copy(outputDir, backupDir);
                                fs.writeFileSync(path.join(backupDir, 'build_result.json'), JSON.stringify(results));
                            }

                            FileUtils.mkdir(path.dirname(buildResultCacheFile));
                            fs.writeFileSync(buildResultCacheFile, JSON.stringify(buildResult));
                            console.warn(`save build result ${buildResultCacheFile}`)

                        }
                        break;
                    case 'web-mobile':
                        {
                            for (const key of keys) {
                                PackageWeb(project, key, isolate);
                            }
                        }
                        break;
                }


            }
            break;
    }
})();
