/**
 * ------------------------------------------------------------------------
 * 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.
 * node build.js --env dev # the same as "debug", dev the content of docs.
 * # Check `./config` to see the available env
 * ```
 * ------------------------------------------------------------------------
 */

const md2json = require('./tool/md2json');
const {extractDesc, extractOptionKeys} = require('./tool/schemaHelper');
const fs = require('fs');
const fse = require('fs-extra');
const marked = require('marked');
const copydir = require('copy-dir');
const chalk = require('chalk');
// const MarkDownTOCRenderer = require('./tool/MarkDownTOCRenderer');
const argv = require('yargs').argv;
const path = require('path');
const assert = require('assert');
const chokidar = require('chokidar');
const debounce = require('lodash.debounce');
const {getDocJSONPVarNname} = require('./src/shared');

const projectDir = __dirname;

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

    if (isDev) {
        console.warn('=============================');
        console.warn('!!! THIS IS IN DEV MODE !!!');
        console.warn('=============================');
        envType = 'dev';
    }

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

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

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

    config.envType = envType;

    return config;
}

const config = initEnv();

const languages = ['zh', 'en'];

config.gl = config.gl || {};
for (let key in config) {
    if (key !== 'gl' && !config.gl.hasOwnProperty(key)) {
        config.gl[key] = config[key];
    }
}

async function md2jsonAsync(opt) {

    var newOpt = Object.assign({
        path: path.join(opt.language, opt.entry, '**/*.md'),
        tplEnv: Object.assign({}, config, {
            galleryViewPath: config.galleryViewPath.replace('${lang}', opt.language),
            galleryEditorPath: config.galleryEditorPath.replace('${lang}', opt.language)
        }),
        imageRoot: config.imagePath
    }, opt);

    function run(cb) {
        md2json(newOpt).then(schema => {
            writeSingleSchema(schema, opt.language, opt.entry, false);
            writeSingleSchemaPartioned(schema, opt.language, opt.entry, false);
            console.log(chalk.green('generated: ' + opt.language + '/' + opt.entry));
            cb && cb();
        }).catch(e => {
            console.log(e);
        });
    }

    var runDebounced = debounce(run, 500, {
        leading: false,
        trailing: true
    });
    return await new Promise((resolve, reject) => {
        run(resolve);

        if (argv.watch) {
            chokidar.watch(path.resolve(__dirname, opt.language, opt.entry), {
                ignoreInitial: true
            }).on('all', (event, path) => {
                console.log(path, event);
                runDebounced();
            });
        }
    });
}

function copyAsset() {

    const assetSrcDir = path.resolve(projectDir, 'asset');

    function doCopy() {
        for (let lang of languages) {
            const assetDestDir = path.resolve(config.releaseDestDir, `${lang}/documents/asset`);
            copydir.sync(assetSrcDir, assetDestDir);
        }
    }
    var doCopyDebounced = debounce(doCopy, 500, {
        leading: false,
        trailing: true
    });

    doCopy();

    if (argv.watch) {
        chokidar.watch(assetSrcDir, {
            ignoreInitial: true
        }).on('all', (event, path) => {
            console.log(path, event);
            doCopyDebounced();
        });
    }
    console.log('Copy asset done.');
}

async function run() {

    for (let language of languages) {
        await md2jsonAsync({
            sectionsAnyOf: ['visualMap', 'dataZoom', 'series', 'graphic.elements', 'dataset.transform'],
            entry: 'option',
            language
        });

        await md2jsonAsync({
            entry: 'tutorial',
            maxDepth: 1,
            language
        });

        await md2jsonAsync({
            entry: 'api',
            language
        });

        await md2jsonAsync({
            sectionsAnyOf: ['series'],
            entry: 'option-gl',
            // Overwrite
            tplEnv: config.gl,
            imageRoot: config.gl.imagePath,
            language
        });
    }

    console.log('Build doc done.');

    copyAsset();

    if (!argv.watch) {  // Not in watch dev mode
        try {
            // TODO Do we need to debug changelog in the doc folder?
            buildChangelog();
            buildCodeStandard();

            copySite();
        }
        catch (e) {
            console.log('Error happens when copying to dest folders.');
            console.log(e);
        }
    }

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

function buildChangelog() {
    for (let lang of languages) {
        const srcPath = path.resolve(projectDir, `${lang}/changelog.md`);
        const destPath = path.resolve(config.ecWWWGeneratedDir, `${lang}/documents/changelog-content.html`);
        fse.outputFileSync(
            destPath,
            marked(fs.readFileSync(srcPath, 'utf-8')),
            'utf-8'
        );
        console.log(chalk.green('generated: ' + destPath));
    }
    console.log('Build changelog done.');
}

function buildCodeStandard() {
    // support for Chinese character
    const customRenderer = new marked.Renderer();
    customRenderer.heading = function(text, level, raw) {
        const id = raw.toLowerCase().replace(/[^\w\u4e00-\u9fa5]+/g, '-');
        return `<h${level} id="${id}">${text}</h${level}>\n`;
    };

    for (let lang of languages) {
        const codeStandardDestPath = path.resolve(config.ecWWWGeneratedDir, `${lang}/coding-standard-content.html`);
        fse.ensureDirSync(path.dirname(codeStandardDestPath));
        fse.outputFileSync(
            codeStandardDestPath,
            marked(fs.readFileSync(`${lang}/coding-standard.md`, 'utf-8'), { renderer: customRenderer }),
            'utf-8'
        );
        console.log(chalk.green('generated: ' + codeStandardDestPath));
    }

    console.log('Build code standard done.');
}

function copySite() {
    const jsSrcPath = path.resolve(projectDir, 'public/js/doc-bundle.js');
    const cssSrcDir = path.resolve(projectDir, 'public/css');

    // Copy js and css of doc site.
    for (let lang of languages) {
        const jsDestPath = path.resolve(config.releaseDestDir, `${lang}/js/doc-bundle.js`);
        fse.copySync(jsSrcPath, jsDestPath);
        console.log(chalk.green(`js copied to: ${jsDestPath}`));

        const cssDestDir = path.resolve(config.releaseDestDir, `${lang}/css`);
        fse.copySync(cssSrcDir, cssDestDir);
        console.log(chalk.green(`css copied to: ${cssDestDir}`));
    }

    console.log('Copy site done.');
}

function writeSingleSchema(schema, language, docName, format) {
    const destPath = path.resolve(config.releaseDestDir, `${language}/documents/${docName}.json`);
    fse.ensureDirSync(path.dirname(destPath));
    fse.outputFileSync(
        destPath,
        format ? JSON.stringify(schema, null, 2) : JSON.stringify(schema),
        'utf-8'
    );
    // console.log(chalk.green('generated: ' + destPath));
}

function writeSingleSchemaPartioned(schema, language, docName, format) {
    const {outline, descriptions} = extractDesc(schema, docName);

    function convertToJS(basename, filePath) {
        const content = fs.readFileSync(filePath, 'utf-8');
        const varName = getDocJSONPVarNname(basename);
        const code = `window.${varName} = ${content}`;
        fs.writeFileSync(filePath.replace(/\.json$/, '.js'), code, 'utf-8');
    }

    const outlineBasename = `${docName}-outline.json`;
    const outlineDestPath = path.resolve(config.releaseDestDir, `${language}/documents/${docName}-parts/${outlineBasename}`);
    fse.ensureDirSync(path.dirname(outlineDestPath));
    fse.outputFileSync(
        outlineDestPath,
        format ? JSON.stringify(outline, null, 2) : JSON.stringify(outline),
        'utf-8'
    );
    convertToJS(outlineBasename, outlineDestPath);

    function copyUIControlConfigs(source, target) {
        for (let key in source) {
            if (target[key]) {
                if (source[key].uiControl && !target[key].uiControl) {
                    target[key].uiControl = source[key].uiControl;
                }
                if (source[key].exampleBaseOptions && !target[key].exampleBaseOptions) {
                    target[key].exampleBaseOptions = source[key].exampleBaseOptions;
                }
            }
            else {
                // console.error(`Unmatched option path ${key}`);
            }
        }
    }

    function readOptionDesc(language, partKey) {
        const descDestPath = path.resolve(config.releaseDestDir, `${language}/documents/${docName}-parts/${partKey}.json`);
        try {
            const text = fs.readFileSync(descDestPath, 'utf-8');
            return JSON.parse(text);
        }
        catch(e) {
            return;
        }
    }

    function writeOptionDesc(language, partKey, json) {
        const descBasename = `${partKey}.json`;
        const descDestPath = path.resolve(config.releaseDestDir, `${language}/documents/${docName}-parts/${descBasename}`);
        fse.ensureDirSync(path.dirname(descDestPath));
        const content = JSON.stringify(json, null, 2);
        fse.outputFileSync(
            descDestPath,
            // format ? JSON.stringify(partDescriptions, null, 2) : JSON.stringify(partDescriptions),
            content,
            'utf-8'
        );
        // Convnert to JS
        convertToJS(descBasename, descDestPath);
    }

    for (let partKey in descriptions) {
        let partDescriptions = descriptions[partKey];

        // Copy ui control config from zh to english.
        if (language === 'zh') {
            languages.forEach(function (otherLang) {
                if (otherLang === 'zh') {
                    return;
                }
                const json = readOptionDesc(otherLang, partKey);
                if (json) {
                    copyUIControlConfigs(partDescriptions, json);
                    writeOptionDesc(otherLang, partKey, json);
                }
            });
        }
        else {
            const json = readOptionDesc('zh', partKey);
            if (json) {
                copyUIControlConfigs(json, partDescriptions);
            }
        }

        writeOptionDesc(language, partKey, partDescriptions);
        // console.log(chalk.green('generated: ' + descDestPath));
    }
};

run();
