#!/usr/bin/env node

const path = require('path');
const program = require('commander');
const fs = require('fs');
const fse = require('fs-extra');
const babel = require('babel-core');

const SUPPORTED_FORMATS = new Set(['amd', 'commonjs', 'systemjs', 'umd']);

program
    .option('--as [format]', `output files using various import formats instead of ES6 import and export.  Supports ${Array.from(SUPPORTED_FORMATS)}.`)
    .option('-m, --with-source-maps [type]', 'output source maps when not generating a bundled app (type may be empty for external source maps, inline for inline source maps, or both) ')
    .option('--with-app', 'process app files as well as core files')
    .option('--only-legacy', 'only output legacy files (no ES6 modules) for the app')
    .option('--clean', 'clear the lib folder before building')
    .parse(process.argv);

// the various important paths
const paths = {
    main: path.resolve(__dirname, '..'),
    core: path.resolve(__dirname, '..', 'core'),
    app: path.resolve(__dirname, '..', 'app'),
    vendor: path.resolve(__dirname, '..', 'vendor'),
    out_dir_base: path.resolve(__dirname, '..', 'build'),
    lib_dir_base: path.resolve(__dirname, '..', 'lib'),
};

const no_copy_files = new Set([
    // skip these -- they don't belong in the processed application
    path.join(paths.vendor, 'sinon.js'),
    path.join(paths.vendor, 'browser-es-module-loader'),
    path.join(paths.vendor, 'promise.js'),
    path.join(paths.app, 'images', 'icons', 'Makefile'),
]);

const no_transform_files = new Set([
    // don't transform this -- we want it imported as-is to properly catch loading errors
    path.join(paths.app, 'error-handler.js'),
]);

no_copy_files.forEach(file => no_transform_files.add(file));

// util.promisify requires Node.js 8.x, so we have our own
function promisify(original) {
    return function promise_wrap() {
        const args = Array.prototype.slice.call(arguments);
        return new Promise((resolve, reject) => {
            original.apply(this, args.concat((err, value) => {
                if (err) return reject(err);
                resolve(value);
            }));
        });
    };
}

const readFile = promisify(fs.readFile);
const writeFile = promisify(fs.writeFile);

const readdir = promisify(fs.readdir);
const lstat = promisify(fs.lstat);

const copy = promisify(fse.copy);
const unlink = promisify(fse.unlink);
const ensureDir = promisify(fse.ensureDir);
const rmdir = promisify(fse.rmdir);

const babelTransformFile = promisify(babel.transformFile);

// walkDir *recursively* walks directories trees,
// calling the callback for all normal files found.
function walkDir(base_path, cb, filter) {
    return readdir(base_path)
        .then((files) => {
            const paths = files.map(filename => path.join(base_path, filename));
            return Promise.all(paths.map(filepath => lstat(filepath)
                .then((stats) => {
                    if (filter !== undefined && !filter(filepath, stats)) return;

                    if (stats.isSymbolicLink()) return;
                    if (stats.isFile()) return cb(filepath);
                    if (stats.isDirectory()) return walkDir(filepath, cb, filter);
                })));
        });
}

function transform_html(legacy_scripts, only_legacy) {
    // write out the modified vnc.html file that works with the bundle
    const src_html_path = path.resolve(__dirname, '..', 'vnc.html');
    const out_html_path = path.resolve(paths.out_dir_base, 'vnc.html');
    return readFile(src_html_path)
        .then((contents_raw) => {
            let contents = contents_raw.toString();

            const start_marker = '<!-- begin scripts -->\n';
            const end_marker = '<!-- end scripts -->';
            const start_ind = contents.indexOf(start_marker) + start_marker.length;
            const end_ind = contents.indexOf(end_marker, start_ind);

            let new_script = '';

            if (only_legacy) {
            // Only legacy version, so include things directly
                for (let i = 0;i < legacy_scripts.length;i++) {
                    new_script += `    <script src="${legacy_scripts[i]}"></script>\n`;
                }
            } else {
            // Otherwise detect if it's a modern browser and select
            // variant accordingly
                new_script += `\
    <script type="module">\n\
        window._noVNC_has_module_support = true;\n\
    </script>\n\
    <script>\n\
        window.addEventListener("load", function() {\n\
            if (window._noVNC_has_module_support) return;\n\
            let legacy_scripts = ${JSON.stringify(legacy_scripts)};\n\
            for (let i = 0;i < legacy_scripts.length;i++) {\n\
                let script = document.createElement("script");\n\
                script.src = legacy_scripts[i];\n\
                script.async = false;\n\
                document.head.appendChild(script);\n\
            }\n\
        });\n\
    </script>\n`;

            // Original, ES6 modules
                new_script += '    <script type="module" crossorigin="anonymous" src="app/ui.js"></script>\n';
            }

            contents = contents.slice(0, start_ind) + `${new_script}\n` + contents.slice(end_ind);

            return contents;
        })
        .then((contents) => {
            console.log(`Writing ${out_html_path}`);
            return writeFile(out_html_path, contents);
        });
}

function make_lib_files(import_format, source_maps, with_app_dir, only_legacy) {
    if (!import_format) {
        throw new Error("you must specify an import format to generate compiled noVNC libraries");
    } else if (!SUPPORTED_FORMATS.has(import_format)) {
        throw new Error(`unsupported output format "${import_format}" for import/export -- only ${Array.from(SUPPORTED_FORMATS)} are supported`);
    }

    // NB: we need to make a copy of babel_opts, since babel sets some defaults on it
    const babel_opts = () => ({
        plugins: [`transform-es2015-modules-${import_format}`],
        presets: ['es2015'],
        ast: false,
        sourceMaps: source_maps,
    });

    // No point in duplicate files without the app, so force only converted files
    if (!with_app_dir) {
        only_legacy = true;
    }

    let in_path;
    let out_path_base;
    if (with_app_dir) {
        out_path_base = paths.out_dir_base;
        in_path = paths.main;
    } else {
        out_path_base = paths.lib_dir_base;
    }
    const legacy_path_base = only_legacy ? out_path_base : path.join(out_path_base, 'legacy');

    fse.ensureDirSync(out_path_base);

    const helpers = require('./use_require_helpers');
    const helper = helpers[import_format];

    const outFiles = [];

    const handleDir = (js_only, vendor_rewrite, in_path_base, filename) => Promise.resolve()
        .then(() => {
            if (no_copy_files.has(filename)) return;

            const out_path = path.join(out_path_base, path.relative(in_path_base, filename));
            const legacy_path = path.join(legacy_path_base, path.relative(in_path_base, filename));

            if (path.extname(filename) !== '.js') {
                if (!js_only) {
                    console.log(`Writing ${out_path}`);
                    return copy(filename, out_path);
                }
                return;  // skip non-javascript files
            }

            return Promise.resolve()
                .then(() => {
                    if (only_legacy && !no_transform_files.has(filename)) {
                        return;
                    }
                    return ensureDir(path.dirname(out_path))
                        .then(() => {
                            console.log(`Writing ${out_path}`);
                            return copy(filename, out_path);
                        });
                })
                .then(() => ensureDir(path.dirname(legacy_path)))
                .then(() => {
                    if (no_transform_files.has(filename)) {
                        return;
                    }

                    const opts = babel_opts();
                    if (helper && helpers.optionsOverride) {
                        helper.optionsOverride(opts);
                    }
            // Adjust for the fact that we move the core files relative
            // to the vendor directory
                    if (vendor_rewrite) {
                        opts.plugins.push(["import-redirect",
                                           {"root": legacy_path_base,
                                            "redirect": { "vendor/(.+)": "./vendor/$1"}}]);
                    }

                    return babelTransformFile(filename, opts)
                        .then((res) => {
                            console.log(`Writing ${legacy_path}`);
                            const {map} = res;
                            let {code} = res;
                            if (source_maps === true) {
                    // append URL for external source map
                                code += `\n//# sourceMappingURL=${path.basename(legacy_path)}.map\n`;
                            }
                            outFiles.push(`${legacy_path}`);
                            return writeFile(legacy_path, code)
                                .then(() => {
                                    if (source_maps === true || source_maps === 'both') {
                                        console.log(`  and ${legacy_path}.map`);
                                        outFiles.push(`${legacy_path}.map`);
                                        return writeFile(`${legacy_path}.map`, JSON.stringify(map));
                                    }
                                });
                        });
                });
        });

    if (with_app_dir && helper && helper.noCopyOverride) {
        helper.noCopyOverride(paths, no_copy_files);
    }

    Promise.resolve()
        .then(() => {
            const handler = handleDir.bind(null, true, false, in_path || paths.main);
            const filter = (filename, stats) => !no_copy_files.has(filename);
            return walkDir(paths.vendor, handler, filter);
        })
        .then(() => {
            const handler = handleDir.bind(null, true, !in_path, in_path || paths.core);
            const filter = (filename, stats) => !no_copy_files.has(filename);
            return walkDir(paths.core, handler, filter);
        })
        .then(() => {
            if (!with_app_dir) return;
            const handler = handleDir.bind(null, false, false, in_path);
            const filter = (filename, stats) => !no_copy_files.has(filename);
            return walkDir(paths.app, handler, filter);
        })
        .then(() => {
            if (!with_app_dir) return;

            if (!helper || !helper.appWriter) {
                throw new Error(`Unable to generate app for the ${import_format} format!`);
            }

            const out_app_path = path.join(legacy_path_base, 'app.js');
            console.log(`Writing ${out_app_path}`);
            return helper.appWriter(out_path_base, legacy_path_base, out_app_path)
                .then((extra_scripts) => {
                    const rel_app_path = path.relative(out_path_base, out_app_path);
                    const legacy_scripts = extra_scripts.concat([rel_app_path]);
                    transform_html(legacy_scripts, only_legacy);
                })
                .then(() => {
                    if (!helper.removeModules) return;
                    console.log(`Cleaning up temporary files...`);
                    return Promise.all(outFiles.map((filepath) => {
                        unlink(filepath)
                            .then(() => {
                    // Try to clean up any empty directories if this
                    // was the last file in there
                                const rmdir_r = dir =>
                                    rmdir(dir)
                                        .then(() => rmdir_r(path.dirname(dir)))
                                        .catch(() => {
                            // Assume the error was ENOTEMPTY and ignore it
                                        });
                                return rmdir_r(path.dirname(filepath));
                            });
                    }));
                });
        })
        .catch((err) => {
            console.error(`Failure converting modules: ${err}`);
            process.exit(1);
        });
}

if (program.clean) {
    console.log(`Removing ${paths.lib_dir_base}`);
    fse.removeSync(paths.lib_dir_base);

    console.log(`Removing ${paths.out_dir_base}`);
    fse.removeSync(paths.out_dir_base);
}

make_lib_files(program.as, program.withSourceMaps, program.withApp, program.onlyLegacy);
