const fs = require('fs');
const fse = require('fs-extra');
const sass = require('node-sass');
const less = require('less');
const globby = require('globby');
const chalk = require('chalk');
const autoprefixer = require('autoprefixer');
const postcss = require('postcss');
const jade = require('jade');
const path = require('path');
const uglify = require('uglify-js');
const argv = require('yargs').argv;
const assert = require('assert');
const requirejs = require('requirejs');
const readline = require('readline');
const md5 = require('md5');

const LANGUAGES = ['zh', 'en'];
const projectDir = path.resolve(__dirname, '..');

/**
 * ----------------------------------------------------------------------------------
 * Usage:
 *
 * ```shell
 * node build.js --env asf # build all for asf
 * node build.js --env echartsjs # build all for echartsjs.
 * node build.js --env localsite # build all for localsite.
 * # Check `../config` to see the available env
 *
 * node build.js --env asf --clean
 * node build.js --env echartsjs --clean
 * node build.js --env localsite --clean
 *
 * # Build all files by default.
 * # If you wish to build sass and jade only:
 * node build.js --env localsite --filter=sass,jade
 * # Supported: sass,jade,js
 * ```
 * ----------------------------------------------------------------------------------
 */

function initEnv() {
    var envType = argv.env;
    var isDev = argv.dev != null || argv.debug != null || envType === 'debug' || envType === 'dev';

    if (isDev) {
        console.warn('====================================================================');
        console.warn('THIS IS IN DEV MODE');
        console.warn('!!! Please input your local host in `config/env.dev.js` firstly !!!');
        console.warn('====================================================================');
        envType = 'dev';
    }

    if (!envType) {
        throw new Error('--env MUST be specified');
    }

    var config = require('../config/env.' + envType);

    if (isDev) {
        console.warn('====================================================================');
        console.warn('Please visit the website: ');
        console.warn(config.host);
        console.warn('====================================================================');
    }

    var filter = argv.filter || 'all';
    if (argv.filter) {
        console.warn('====================================================================');
        console.warn('Build only: ' + argv.filter);
        console.warn('====================================================================');
    }
    config.filter = filter;

    assert(path.isAbsolute(config.releaseDestDir));

    config.getAssetUrl = function (cdnPayRoot, filePath) {
        const fullFilePath = path.join(config.releaseDestDir, filePath);
        let content;
        try {
            content = fs.readFileSync(fullFilePath, 'utf-8');
        }
        catch (e) {
            throw new Error(`Unkown file ${fullFilePath}`);
        }
        const hash = md5(content);
        return cdnPayRoot + '/' + filePath + '?_v_=' + hash.substr(-10);
    };
    // Update home version each build.
    config.homeVersion = +new Date();
    // Temp: give a fixed version until need to update.
    config.cdnPayVersion = '20200710_1';

    config.downloadVersion = '5.0.0';

    config.envType = envType;

    config.copyRightYear = new Date().getFullYear();

    return config;
}

async function clean(config) {
    let destDir = path.resolve(config.releaseDestDir);

    fse.ensureDirSync(destDir);

    const srcRelativePathList = await globby([
        '**/*',
        '!.*', // .git .gitignore .htaccess .scripts .github
        '!v4/**/*', // v4 website
        '!README.md'
    ], {
        cwd: destDir
    });

    for (let i = 0; i < srcRelativePathList.length; i++) {
        let srcRelativePath = srcRelativePathList[i];
        let srcAbsolutePath = path.resolve(destDir, srcRelativePath);

        fs.unlinkSync(srcAbsolutePath);

        replaceLog(chalk.blue('deleted files: ' + (i + 1) + '/' + srcRelativePathList.length + '. '));
    }

    console.log('\nclean done.');
}

async function buildSASS(config) {
    for (let lang of LANGUAGES) {
        let cssContent = await new Promise((resolve, reject) => {
            sass.render({
                file: path.resolve(projectDir, '_scss/main.scss'),
                includePaths: ['scss'],
                outputStyle: 'compressed'
            }, function (err, result) {
                if (err) {
                    console.error(chalk.red(err));
                    reject();
                }
                else {
                    resolve(result.css);
                }
            });
        });

        const result = await postcss(
            autoprefixer(['last 15 versions', '> 1%', 'ie 8', 'ie 7'], {cascade: true})
        ).process(cssContent, {
            map: false,
            from: undefined
        });

        let destPath = path.resolve(config.releaseDestDir, lang, './css/main.css');
        fse.ensureDirSync(path.dirname(destPath));
        fs.writeFileSync(destPath, result.css, 'utf8');
        console.log(chalk.green(`generated: ${destPath}`));
    }

    console.log('buildSASS done.');
}

async function getFolderHash(globPattern) {
    const files = await globby(globPattern);
    if (!files.length) {
        throw new Error('No file exists for pattern ' + globPattern);
    }
    let concatedStr = '';
    for (let file of files) {
        const content = fs.readFileSync(file);
        concatedStr += md5(content);
    }
    assert(concatedStr);
    return md5(concatedStr).substr(-10);
}

async function buildJade(config) {
    const basePath = path.resolve(projectDir, '_jade');
    const srcPaths = await globby([
        '**/*.jade'
    ], {
        cwd: basePath
    });

    const hashes = {};
    for (let lang of ['zh', 'en']) {
        hashes[lang] = {
            docHash: await getFolderHash(path.resolve(config.releaseDestDir, lang, 'documents/**/*.js'))
        };
    }

    for (let srcPath of srcPaths) {
        let filePath = path.resolve(basePath, srcPath);

        const lang = (srcPath.indexOf('zh/') === 0
            || srcPath.indexOf('examples/zh/') === 0) ? 'zh' : 'en';

        assert(hashes[lang]);

        const cfg = Object.assign({}, config, hashes[lang]);
        cfg.cdnPayRoot = config.cdnPayRootMap[lang];
        cfg.cdnFreeRoot = config.cdnFreeRootMap[lang];

        let destPath = path.resolve(cfg.releaseDestDir, srcPath.replace('.jade', '.html'));

        // This props can be read in jade tpl, like: `#{cdnPayRoot}`
        assert(
            cfg.cdnPayRoot
            && cfg.cdnFreeRoot
            && cfg.host
            && cfg.cdnThirdParty
            && cfg.galleryPath
            && cfg.releaseDestDir
            && cfg.homeVersion
            && cfg.cdnPayVersion
        );

        process.stdout.write(`generating: ${destPath} ...`);

        try {
            let compiledFunction = jade.compileFile(filePath);
            let html = compiledFunction(cfg);

            fse.ensureDirSync(path.dirname(destPath));
            fs.writeFileSync(destPath, html, 'utf8');

            console.log(chalk.green(` Done.`));
        }
        catch (err) {
            console.error(err.stack);
            console.error(err);
        }
    }

    console.log('buildJade done.');
}

async function buildJS(config) {
    const srcRelativePathList = await globby([
        'js/*.js',
        '!js/spreadsheet/**/*'
    ], {
        cwd: projectDir
    });
    for (let lang of LANGUAGES) {
        for (let srcRelativePath of srcRelativePathList) {
            let srcAbsolutePath = path.resolve(projectDir, srcRelativePath);
            let content = fs.readFileSync(srcAbsolutePath, 'utf8');

            let result = uglify.minify(content);
            if (result.error) {
                console.log(chalk.red(srcAbsolutePath));
                console.error(result.error);
                process.exit(1);
            }

            let destPath = path.resolve(config.releaseDestDir, lang, srcRelativePath);
            fse.ensureDirSync(path.dirname(destPath));
            fs.writeFileSync(destPath, result.code, 'utf8');

            console.log(chalk.green(`generated: ${destPath}`));
        }
    }

    console.log('buildJS done.');
}

async function copyResource(config) {
    const srcRelativePathList = await globby([
        'vendors/**/*',
        'images/**/*',
        'asset/map/**/*',
        'asset/theme/**/*',
        'asset/lottie/**/*',
        'builder/**/*',
        'dist/**/*',
        'video/**/*'
    ], {
        cwd: projectDir
    });

    console.log();

    for (let lang of LANGUAGES) {
        for (let i = 0; i < srcRelativePathList.length; i++) {
            let srcRelativePath = srcRelativePathList[i];
            let srcAbsolutePath = path.resolve(projectDir, srcRelativePath);
            let destAbsolutePath = path.resolve(config.releaseDestDir, lang, srcRelativePath);

            fse.ensureDirSync(path.dirname(destAbsolutePath));
            fs.copyFileSync(srcAbsolutePath, destAbsolutePath);

            replaceLog('(' + (i + 1) + '/' + srcRelativePathList.length + ') ' + chalk.green(`resource copied to: ${destAbsolutePath}`));
        }
    }

    console.log('\ncopyResources done.');
}

async function updateSourceVersion(config) {
    for (let lang of LANGUAGES) {
        let filePath = path.resolve(config.releaseDestDir, lang, 'builder/echarts.html');
        let content = fs.readFileSync(filePath, 'utf8');
        content = content.replace(/(urlArgs:\s*\'v=)([0-9rc\.-]+)\'/, '$1' + config.homeVersion + '\'');
        fs.writeFileSync(filePath, content, 'utf8');
        console.log(chalk.green(`sourceVersion updated: ${filePath}`));
    }
}

async function makeCDNChecker(config) {
    const relativePath = 'zh/css/only_for_cdn_ready_check.css';
    const targetPath = path.resolve(config.releaseDestDir, relativePath);
    const content = `/* ${config.homeVersion} OK */`;
    fs.writeFileSync(targetPath, content, 'utf8');
    const cdnPayRoot = config.cdnPayRootMap.zh;
    const homeVersion = config.homeVersion;

    console.log(chalk.green('================================================='));
    console.log(chalk.green('====== CDN checker =============================='));
    console.log(`Please waite for a while, and then use this shell cmd to check: `);
    console.log(chalk.green(`curl "${cdnPayRoot}/${relativePath}?_v_=${homeVersion}_test_1" | grep ${homeVersion}`));
    console.log(`If there is no ${chalk.green('OK')} printed, wait for a while and then use this cmd to check again:`);
    console.log(chalk.green(`curl "${cdnPayRoot}/${relativePath}?_v_=${homeVersion}_test_2" | grep ${homeVersion}`));
    console.log(`repeat this process until ${chalk.green('OK')} printed.`);
    console.log(chalk.green('================================================='));
}

async function buildLegacyDoc(config) {
    // Build JS
    let jsDestPathZH = path.resolve(config.releaseDestDir, './zh/js/docTool/main.js');
    let jsDestPathEN = path.resolve(config.releaseDestDir, './en/js/docTool/main.js');

    let docToolConfig = {
        optimize: 'uglify',
        // optimize: 'none',
        name: 'docTool/main',
        exclude: ['globalArgs', 'prettyPrint'],
        out: jsDestPathZH,
        baseUrl: './legacy/js',
        paths: {
            dt: '../../vendors/dt/0.0.1',
            tpl: '../../vendors/dt/0.0.1/tplLoader',
            etpl: '../../vendors/etpl/3.0.0/etpl.min',
            signals: '../../vendors/signals/1.0.0/signals.min',
            hasher: '../../vendors/hasher/1.2.0/hasher.min',
            jquery: '../../vendors/jquery/jquery.min',
            perfectScrollbar: '../../vendors/perfect-scrollbar/0.6.8/js/perfect-scrollbar'
        },
        rawText: {
            'globalArgs': 'define(function () {});',
            'prettyPrint': 'define(function () {});'
        }
    };

    await new Promise((reslove, reject) => {
        requirejs.optimize(
            docToolConfig,
            function () {
                fse.ensureDirSync(path.dirname(jsDestPathEN));
                fse.copyFileSync(jsDestPathZH, jsDestPathEN);
                reslove();
            },
            function (error) {
                console.error(chalk.red(`buildLegacyDoc requirejs ${error.message}`));
                process.exit(1);
            }
        );
    });

    // Build less
    let cssSrcPath = path.resolve(projectDir, 'legacy/js/docTool/ecOption.less');
    let cssContent = fs.readFileSync(cssSrcPath, 'utf8');
    let cssResult;
    try {
        cssResult = await less.render(cssContent, {
            paths: ['vendors'],
            javascriptEnabled: true,
            compress: true
        });
    }
    catch (err) {
        console.error(err);
        process.exit(1);
    }
    let cssDestPathZH = path.resolve(config.releaseDestDir, './zh/css/ecOption.css');
    fs.writeFileSync(cssDestPathZH, cssResult.css, 'utf8');
    let cssDestPathEN = path.resolve(config.releaseDestDir, './en/css/ecOption.css');
    fs.writeFileSync(cssDestPathEN, cssResult.css, 'utf8');

    // Copy css assets
    const assetDir = path.resolve(projectDir, 'legacy/css');
    const assetPaths = await globby(['**/*'], {cwd: assetDir});
    for (let assetPath of assetPaths) {
        let assetSrcPath = path.resolve(assetDir, assetPath);
        let assetDestPathZH = path.resolve(config.releaseDestDir, './zh/css', assetPath);
        let assetDestPathEN = path.resolve(config.releaseDestDir, './en/css', assetPath);
        fse.ensureDirSync(path.dirname(assetDestPathZH));
        fse.copyFileSync(assetSrcPath, assetDestPathZH);
        fse.ensureDirSync(path.dirname(assetDestPathEN));
        fse.copyFileSync(assetSrcPath, assetDestPathEN);
    }

    // Copy tpl.html
    let tplSrcPath = path.resolve(projectDir, 'legacy/js/docTool/main.tpl.html');
    let tplDestPathZH = path.resolve(config.releaseDestDir, './zh/js/docTool/main.tpl.html');
    let tplDestPathEN = path.resolve(config.releaseDestDir, './en/js/docTool/main.tpl.html');
    fse.ensureDirSync(path.dirname(tplDestPathZH));
    fse.copyFileSync(tplSrcPath, tplDestPathZH);
    fse.ensureDirSync(path.dirname(tplDestPathEN));
    fse.copyFileSync(tplSrcPath, tplDestPathEN);

    // Copy option3.json
    let option3SrcPath = path.resolve(projectDir, 'legacy/option3.json');
    let option3DestPath = path.resolve(config.releaseDestDir, './zh/documents/option3.json');
    fse.ensureDirSync(path.dirname(option3DestPath));
    fse.copyFileSync(option3SrcPath, option3DestPath);

    console.log('\nBuild legacy doc done.');
}

async function buildSpreadsheet(config) {
    // Build JS
    let jsDestPathZH = path.resolve(config.releaseDestDir, './zh/js/spreadsheet/spreadsheet.js');
    let jsDestPathEN = path.resolve(config.releaseDestDir, './en/js/spreadsheet/spreadsheet.js');

    let spreadsheetConfig = {
        optimize: 'uglify',
        // optimize: 'none',
        name: 'spreadsheet/spreadsheet',
        exclude: ['globalArgs'],
        out: jsDestPathZH,
        baseUrl: './js',
        paths: {
            dt: '../vendors/dt/0.0.1',
            tpl: '../vendors/dt/0.0.1/tplLoader',
            etpl: '../vendors/etpl/3.0.0/etpl.min',
            signals: '../vendors/signals/1.0.0/signals.min',
            hasher: '../vendors/hasher/1.2.0/hasher.min',
            jquery: '../vendors/jquery/jquery.min',
            jquerymousewheel: '../vendors/jquery-mousewheel/3.1.11/jquery.mousewheel.min',
            handsontable: '../vendors/handsontable/0.26.1/dist/handsontable.full.min',
            latinize: '../vendors/latinize/latinize',
            numeral: '../vendors/numeral/1.4.7/numeral.min',
            immutable: '../vendors/immutable/3.7.4/dist/immutable'
        },
        rawText: {
            'globalArgs': 'define(function () {});'
        }
    };

    await new Promise((resolve, reject) => {
        requirejs.optimize(
            spreadsheetConfig,
            function () {
                fse.ensureDirSync(path.dirname(jsDestPathEN));
                fse.copyFileSync(jsDestPathZH, jsDestPathEN);
                resolve();
            },
            function (error) {
                console.error(chalk.red(`buildSpreadsheet requirejs failed ${error.message}`));
                process.exit(1);
            }
        );
    });

    // Build less
    let cssSrcPath = path.resolve(projectDir, 'js/spreadsheet/spreadsheet.less');
    let cssContent = fs.readFileSync(cssSrcPath, 'utf8');
    let cssResult;
    try {
        cssResult = await less.render(cssContent, {
            paths: ['vendors'],
            javascriptEnabled: true,
            compress: true
        });
    }
    catch (err) {
        console.error(err);
        process.exit(1);
    }
    let cssDestPathZH = path.resolve(config.releaseDestDir, './zh/css/spreadsheet.css');
    fs.writeFileSync(cssDestPathZH, cssResult.css, 'utf8');
    let cssDestPathEN = path.resolve(config.releaseDestDir, './en/css/spreadsheet.css');
    fs.writeFileSync(cssDestPathEN, cssResult.css, 'utf8');

    // Copy tpl.html
    let tplSrcPath = path.resolve(projectDir, 'js/spreadsheet/spreadsheet.tpl.html');
    let tplDestPathZH = path.resolve(config.releaseDestDir, './zh/js/spreadsheet/spreadsheet.tpl.html');
    let tplDestPathEN = path.resolve(config.releaseDestDir, './en/js/spreadsheet/spreadsheet.tpl.html');
    fse.ensureDirSync(path.dirname(tplDestPathZH));
    fse.copyFileSync(tplSrcPath, tplDestPathZH);
    fse.ensureDirSync(path.dirname(tplDestPathEN));
    fse.copyFileSync(tplSrcPath, tplDestPathEN);

    console.log('\nBuild spreadsheet done.');
}

function replaceLog(log) {
    readline.cursorTo(process.stdout, 0);
    process.stdout.write(log);
}

async function run() {
    const config = initEnv();

    if (argv.clean) {
        await clean(config);
    }
    else {
        if (config.filter === 'all') {
            await buildSASS(config);
            await buildJS(config);
            await copyResource(config);
            await updateSourceVersion(config);

            await buildLegacyDoc(config);
            await buildSpreadsheet(config);

            // Build jade at last because it needs to read the resources.
            await buildJade(config);

            await makeCDNChecker(config);
        }
        else {
            const filters = config.filter.split(',');
            for (let i = 0; i < filters.length; ++i) {
                switch (filters[i]) {
                    case 'sass':
                        await buildSASS(config);
                        break;

                    case 'jade':
                        await buildJade(config);
                        break;

                    case 'js':
                        await buildJS(config);
                        break;

                    default:
                        console.warn('====================================================================');
                        console.warn('Filter is not supported: ' + filters[i]);
                        console.warn('Valid parameters of `--filter` includes sass, jade and js');
                        console.warn('E.g.: node build.js --env localsite --filter=sass,jade');
                        console.warn('====================================================================');
                }
            }
        }
    }

    console.log('All done.');
}

run();
