import fss from 'fs';
import fs from 'fs-extra';
import Fontmin from 'fontmin';
import * as babel from '@babel/core';
import * as rollup from 'rollup';
import typescript from '@rollup/plugin-typescript';
import rollupBabel from '@rollup/plugin-babel';
import terser from '@rollup/plugin-terser';
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import { splitResorce } from './resource.js';
import compressing from 'compressing';

const type = process.argv[2];
const map = false;
const resorce = false;
const compress = type === 'dist';

(async function () {
    const timestamp = Date.now();
    // 1. 去除未使用的文件
    // const data = (() => {
    //     const data = fss.readFileSync('./public/project/data.js', 'utf-8');
    //     const json = JSON.parse(
    //         data
    //             .split(/(\n|\r\n)/)
    //             .slice(1)
    //             .join('\n')
    //     );
    //     return json;
    // })() as { main: Record<string, string[]> };
    // const main = data.main;
    // try {
    //     const data = [
    //         ['./dist/project/floors', '.js', 'floorIds'],
    //         ['./dist/project/bgms', '', 'bgms'],
    //         ['./dist/project/sounds', '', 'sounds'],
    //         ['./dist/project/images', '', 'images'],
    //         ['./dist/project/animates', '.animate', 'animates'],
    //         ['./dist/project/tilesets', '', 'tilesets'],
    //         ['./dist/project/fonts', '.ttf', 'fonts']
    //     ];
    //     await Promise.all(
    //         data.map(async v => {
    //             const all = await fs.readdir(`${v[0]}`);
    //             const data = main[v[2]].map(vv => vv + v[1]);
    //             all.forEach(async vv => {
    //                 if (!data.includes(vv)) {
    //                     await fs.rm(`${v[0]}/${vv}`);
    //                 }
    //             });
    //         })
    //     );
    //     if (!map) await fs.remove('./dist/maps/');
    //     // 在线查看什么都看不到,这编辑器难道还需要留着吗?
    //     await fs.remove('./dist/_server');
    //     await fs.remove('./dist/editor.html');
    //     await fs.remove('./dist/server.cjs');

    //     await fs.remove('./dist/project/materials/airwall.png');
    //     await fs.remove('./dist/project/materials/ground.png');
    //     await fs.remove('./dist/project/materials/icons_old.png');
    // } catch (e) {
    //     console.log('去除未使用的文件失败!');
    //     console.log(e);
    // }

    // // 2. 压缩字体
    // try {
    //     // 获取要压缩的文字列表,libs & projects下的所有js文件
    //     let texts = ``;
    //     const exclude = `\n \t`;
    //     const libs = await fs.readdir('./public/libs');
    //     const project = await fs.readdir('./public/project');
    //     const floors = await fs.readdir('./public/project/floors');
    //     const assets = await fs.readdir('./dist/assets/');
    //     const all = [
    //         ...libs.map(v => `./public/libs/${v}`),
    //         ...project.map(v => `./public/project/${v}`),
    //         ...floors.map(v => `./public/project/floors/${v}`),
    //         ...assets.map(v => `./dist/assets/${v}`)
    //     ];
    //     for await (const dir of all) {
    //         const stat = await fs.stat(dir);
    //         if (!stat.isFile()) continue;
    //         if (dir.endsWith('.ttf')) continue;
    //         const file = await fs.readFile(dir, 'utf-8');
    //         for (let i = 0; i < file.length; i++) {
    //             const char = file[i];
    //             if (!texts.includes(char) && !exclude.includes(char))
    //                 texts += char;
    //         }
    //     }

    //     // 获取所有字体(直接压缩字体会报错
    //     const fonts = main.fonts;
    //     await Promise.all([
    //         ...fonts.map(v =>
    //             (async () => {
    //                 const fontmin = new Fontmin();
    //                 fontmin
    //                     .src<string>(`./public/project/fonts/${v}.ttf`)
    //                     .dest('./dist/project/fonts')
    //                     .use(
    //                         Fontmin.glyph({
    //                             text: texts
    //                         })
    //                     );
    //                 await new Promise(res => {
    //                     fontmin.run(err => {
    //                         if (err) throw err;
    //                         res('');
    //                     });
    //                 });
    //             })()
    //         )
    //     ]);
    //     await Promise.all([
    //         ...fonts.map(v => {
    //             return fs.rename(
    //                 `./dist/project/fonts/${v}.ttf`,
    //                 `./dist/project/fonts/${v}-${timestamp}.ttf`
    //             );
    //         })
    //     ]);
    // } catch (e) {
    //     console.log('字体压缩失败');
    //     console.log(e);
    // }

    // 3. 压缩游戏进程
    try {
        await fs.remove('./dist/project/processG.min.js');

        const build = await rollup.rollup({
            input: 'src/game/index.ts',
            plugins: [
                typescript({
                    sourceMap: false,
                    declaration: true,
                    declarationDir: './dist/types/'
                }),
                rollupBabel({
                    // todo: 是否需要添加 polyfill?
                    babelHelpers: 'bundled',
                    sourceType: 'module'
                }),
                terser(),
                resolve(),
                commonjs()
            ]
        });
        await build.write({
            format: 'iife',
            name: 'CorePlugin',
            file: './dist/project/processG.min.js'
        });

        await fs.remove('./dist/project/plugin/');
    } catch (e) {
        console.log('压缩插件失败');
        console.log(e);
    }

    // 4. 压缩main.js
    try {
        // 先获取不能压缩的部分
        const main = (await fs.readFile('./public/main.js', 'utf-8'))
            .replace(
                /this.pluginUseCompress\s*=\s*false\;/,
                'this.pluginUseCompress = true;'
            )
            .replace('this.timestamp = 0', `this.timestamp = ${timestamp};`);

        const endIndex = main.indexOf('// >>>> body end');
        const nonCompress = main.slice(0, endIndex);
        const needCompress = main.slice(endIndex + 17);
        const compressed = babel.transformSync(needCompress)?.code;
        await fs.writeFile('./dist/main.js', nonCompress + compressed, 'utf-8');
    } catch (e) {
        console.log('main.js压缩失败');
        console.log(e);
    }

    // 5. 杂项
    // try {
    //     await fs.copy('./LICENSE', './dist/LICENSE');
    // } catch (e) {
    //     console.log('添加杂项失败');
    //     console.log(e);
    // }

    // 6. 资源分离
    // if (resorce) {
    //     await splitResorce(type);
    // }

    // 7. 压缩
    if (compress) {
        try {
            await fs.ensureDir('./out');
            await compressing.zip.compressDir('./dist', './out/dist.zip');

            // 压缩资源
            if (resorce) {
                const resources = await fs.readdir('./dist-resource');
                for await (const index of resources) {
                    await compressing.zip.compressDir(
                        `./dist-resource/${index}`,
                        `./out/${index}.zip`
                    );
                }
            }
        } catch (e) {
            console.log('压缩为zip失败!');
            console.log(e);
        }
    }
})();