#!/usr/bin/env node

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

const fs = require('fs');
const config = require('./config.js');
const commander = require('commander');
const chalk = require('chalk');
const rollup = require('rollup');
const prePublish = require('./pre-publish');
const transformDEV = require('./transform-dev');
const preamble = require('./preamble');

async function run() {

    /**
     * Tips for `commander`:
     * (1) If arg xxx not specified, `commander.xxx` is undefined.
     *     Otherwise:
     *      If '-x, --xxx', `commander.xxx` can only be true/false, even if '--xxx yyy' input.
     *      If '-x, --xxx <some>', the 'some' string is required, or otherwise error will be thrown.
     *      If '-x, --xxx [some]', the 'some' string is optional, that is, `commander.xxx` can be boolean or string.
     * (2) `node ./build/build.js --help` will print helper info and exit.
     */

    let descIndent = '                                 ';
    let egIndent = '    ';

    commander
        .usage('[options]')
        .description([
            'Build echarts and generate result files in directory `echarts/dist`.',
            '',
            '  For example:',
            '',
            egIndent + 'node build/build.js --release'
                + '\n' + descIndent + '# Build all to `dist` folder.',
            egIndent + 'node build/build.js --prepublish'
                + '\n' + descIndent + '# Only prepublish.',
            egIndent + 'node build/build.js --type ""'
                + '\n' + descIndent + '# Only generate `dist/echarts.js`.',
            egIndent + 'node build/build.js --type common --min'
                + '\n' + descIndent + '# Only generate `dist/echarts.common.min.js`.',
            egIndent + 'node build/build.js --type simple --min'
                + '\n' + descIndent + '# Only generate `dist/echarts-en.simple.min.js`.',
            egIndent + 'node build/build.js -i "my/index.js" -o "my/bundle.js"'
                + '\n' + descIndent + '# Take `<cwd>/my/index.js` as input and generate `<cwd>/my/bundle.js`,'
        ].join('\n'))
        .option(
            '--prepublish',
            'Build all for release'
        )
        .option(
            '--min',
            'Whether to compress the output file, and remove error-log-print code.'
        )
        .option(
            '--type <type name>', [
            'Can be "simple" or "common" or "all" (default). Or can be simple,common,all to build multiple. For example,',
            descIndent + '`--type ""` or `--type "common"`.'
        ].join('\n'))
        .option(
            '--format <format>',
            'The format of output bundle. Can be "umd", "amd", "iife", "cjs", "esm".'
        )
        .parse(process.argv);

    let isPrePublish = !!commander.prepublish;
    let buildType = commander.type || 'all';

    let opt = {
        min: commander.min,
        format: commander.format || 'umd'
    };

    validateIO(opt.input, opt.output);

    if (isPrePublish) {
        await prePublish();
    }
    else if (buildType === 'extension') {
        const cfgs = [
            config.createBMap(opt),
            config.createDataTool(opt)
        ];
        await build(cfgs);
    }
    else if (buildType === 'myTransform') {
        const cfgs = [
            config.createMyTransform(opt)
        ];
        await build(cfgs);
    }
    else {
        const types = buildType.split(',').map(a => a.trim());
        const cfgs = types.map(type =>
            config.createECharts({
                ...opt,
                type
            })
        );
        await build(cfgs);
    }
}

function checkBundleCode(cfg) {
    // Make sure process.env.NODE_ENV is eliminated.
    for (let output of cfg.output) {
        let code = fs.readFileSync(output.file, {encoding: 'utf-8'});
        if (!code) {
            throw new Error(`${output.file} is empty`);
        }
        transformDEV.recheckDEV(code);
        console.log(chalk.green.dim('Check code: correct.'));
    }
}

function validateIO(input, output) {
    if ((input != null && output == null)
        || (input == null && output != null)
    ) {
        throw new Error('`input` and `output` must be both set.');
    }
}

/**
 * @param {Array.<Object>} configs A list of rollup configs:
 *  See: <https://rollupjs.org/#big-list-of-options>
 *  For example:
 *  [
 *      {
 *          ...inputOptions,
 *          output: [outputOptions],
 *      },
 *      ...
 *  ]
 */
async function build(configs) {
    console.log(chalk.yellow(`
    NOTICE: If you are using 'npm run build'. Run 'npm run prepublish' before build !!!
`));

    console.log(chalk.yellow(`
    NOTICE: If you are using syslink on zrender. Run 'npm run prepublish' in zrender first !!
`));

    for (let singleConfig of configs) {
        console.log(
            chalk.cyan.dim('\Bundling '),
            chalk.cyan(singleConfig.input)
        );

        const bundle = await rollup.rollup(singleConfig);

        for (let output of singleConfig.output) {
            console.log(
                chalk.green.dim('Created '),
                chalk.green(output.file),
                chalk.green.dim(' successfully.')
            );

            await bundle.write(output);

            console.time('rollup build');
            console.timeEnd('rollup build');
        };

        checkBundleCode(singleConfig);
    }
}

async function main() {
    try {
        await run();
    }
    catch (err) {
        console.log(chalk.red('BUILD ERROR!'));
        // rollup parse error.
        if (err) {
            if (err.loc) {
                console.warn(chalk.red(`${err.loc.file} (${err.loc.line}:${err.loc.column})`));
                console.warn(chalk.red(err.message));
            }
            if (err.frame) {
                console.warn(chalk.red(err.frame));
            }
            console.log(chalk.red(err ? err.stack : err));

            err.id != null && console.warn(chalk.red(`id: ${err.id}`));
            err.hook != null && console.warn(chalk.red(`hook: ${err.hook}`));
            err.code != null && console.warn(chalk.red(`code: ${err.code}`));
            err.plugin != null && console.warn(chalk.red(`plugin: ${err.plugin}`));
        }
        // console.log(err);
    }
}

main();
