const fs = require('fs');
const swc = require('@swc/core');
const path = require('path');
const util = require('util');
const postcss = require('postcss');
const utils = require('./assets/utils.js');
const assproc = require('./assets/assproc.js');

const rootDir = __dirname;
const modulesDir = path.join(rootDir, 'node_modules');

const assetsDir = path.join(rootDir, 'assets');
const assetsCSS = path.join(assetsDir, 'misuzu.css');
const assetsJS = path.join(assetsDir, 'misuzu.js');
const assetsInfo = path.join(assetsDir, 'current.json');

const pubDir = path.join(rootDir, 'public');
const pubIndex = path.join(pubDir, 'index.html');
const pubAssets = '/assets';
const pubAssetsFull = path.join(pubDir, pubAssets);
const pubAssetCSSFormat = '%s-%s.css';
const pubAssetJSFormat = '%s-%s.js';

const isDebugBuild = fs.existsSync(path.join(rootDir, '.debug'));

const swcJscOptions = {
    target: 'es2016',
    loose: false,
    externalHelpers: false,
    keepClassNames: true,
    preserveAllComments: false,
    transform: {},
    parser: {
        syntax: 'ecmascript',
        jsx: true,
        dynamicImport: false,
        privateMethod: false,
        functionBind: false,
        exportDefaultFrom: false,
        exportNamespaceFrom: false,
        decorators: false,
        decoratorsBeforeExport: false,
        topLevelAwait: true,
        importMeta: false,
    },
    transform: {
        react: {
            runtime: 'classic',
            pragma: '$er',
        },
    },
};

const postcssPlugins = [];
if(!isDebugBuild) postcssPlugins.push(require('cssnano'));
postcssPlugins.push(require('autoprefixer')({
    remove: false,
}));

fs.mkdirSync(pubAssetsFull, { recursive: true });

(async () => {
    const mszCssName = await assproc.process(assetsCSS, { 'prefix': '@', 'entry': 'main.css' })
        .then(output => postcss(postcssPlugins).process(output, { from: assetsCSS }).then(output => {
            const mszCssName = path.join(pubAssets, util.format(pubAssetCSSFormat, 'misuzu', utils.shortHash(output.css)));
            fs.writeFileSync(path.join(pubDir, mszCssName), output.css);
            return mszCssName;
        }));

    const mszJsName = await assproc.process(assetsJS, { 'prefix': '#', 'entry': 'main.js' })
        .then(output => swc.transform(output, {
            filename: 'misuzu.js',
            sourceMaps: false,
            isModule: false,
            minify: !isDebugBuild,
            jsc: swcJscOptions,
        }).then(async output => {
            const mszJsName = path.join(pubAssets, util.format(pubAssetJSFormat, 'misuzu', utils.shortHash(output.code)));
            fs.writeFileSync(path.join(pubDir, mszJsName), output.code);
            return mszJsName;
        }));

    fs.writeFileSync(assetsInfo, JSON.stringify({
        mszjs: mszJsName,
        mszcss: mszCssName,
    }));

    assproc.housekeep(pubAssetsFull);
})();
