/*
* 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.
*/

/**
 * [Create CommonJS files]:
 * Compatible with prevoius folder structure: `echarts/lib` exists in `node_modules`
 * (1) Build all files to CommonJS to `echarts/lib`.
 * (2) Remove __DEV__.
 * (3) Mount `echarts/src/export.js` to `echarts/lib/echarts.js`.
 *
 * [Create ESModule files]:
 * Build all files to CommonJS to `echarts/esm`.
 */

const nodePath = require('path');
const assert = require('assert');
const fs = require('fs');
const fsExtra = require('fs-extra');
const chalk = require('chalk');
const ts = require('typescript');
const globby = require('globby');
const transformDEVUtil = require('./transform-dev');
const preamble = require('./preamble');
const dts = require('@lang/rollup-plugin-dts').default;
const rollup = require('rollup');

const ecDir = nodePath.resolve(__dirname, '..');
const tmpDir = nodePath.resolve(ecDir, 'pre-publish-tmp');

const tsConfig = readTSConfig();

const autoGeneratedFileAlert = `
/**
 * AUTO-GENERATED FILE. DO NOT MODIFY.
 */

`;

const mainSrcGlobby = {
    patterns: [
        'src/**/*.ts'
    ],
    cwd: ecDir
};
const extensionSrcGlobby = {
    patterns: [
        'extension-src/**/*.ts'
    ],
    cwd: ecDir
};
const extensionSrcDir = nodePath.resolve(ecDir, 'extension-src');
const extensionESMDir = nodePath.resolve(ecDir, 'extension');

const typesDir = nodePath.resolve(ecDir, 'types');
const esmDir = 'lib';


const compileWorkList = [
    {
        logLabel: 'main ts -> js-esm',
        compilerOptionsOverride: {
            module: 'ES2015',
            rootDir: ecDir,
            outDir: tmpDir,
            // Generate types when buidling esm
            declaration: true,
            declarationDir: typesDir
        },
        srcGlobby: mainSrcGlobby,
        transformOptions: {
            filesGlobby: {patterns: ['**/*.js'], cwd: tmpDir},
            preamble: preamble.js,
            transformDEV: true
        },
        before: async function () {
            fsExtra.removeSync(tmpDir);
            fsExtra.removeSync(nodePath.resolve(ecDir, 'types'));
            fsExtra.removeSync(nodePath.resolve(ecDir, esmDir));
            fsExtra.removeSync(nodePath.resolve(ecDir, 'index.js'));
            fsExtra.removeSync(nodePath.resolve(ecDir, 'index.blank.js'));
            fsExtra.removeSync(nodePath.resolve(ecDir, 'index.common.js'));
            fsExtra.removeSync(nodePath.resolve(ecDir, 'index.simple.js'));
        },
        after: async function () {
            fs.renameSync(nodePath.resolve(tmpDir, 'src/echarts.all.js'), nodePath.resolve(ecDir, 'index.js'));
            fs.renameSync(nodePath.resolve(tmpDir, 'src/echarts.blank.js'), nodePath.resolve(ecDir, 'index.blank.js'));
            fs.renameSync(nodePath.resolve(tmpDir, 'src/echarts.common.js'), nodePath.resolve(ecDir, 'index.common.js'));
            fs.renameSync(nodePath.resolve(tmpDir, 'src/echarts.simple.js'), nodePath.resolve(ecDir, 'index.simple.js'));
            fs.renameSync(nodePath.resolve(tmpDir, 'src'), nodePath.resolve(ecDir, esmDir));

            transformRootFolderInEntry(nodePath.resolve(ecDir, 'index.js'), esmDir);
            transformRootFolderInEntry(nodePath.resolve(ecDir, 'index.blank.js'), esmDir);
            transformRootFolderInEntry(nodePath.resolve(ecDir, 'index.common.js'), esmDir);
            transformRootFolderInEntry(nodePath.resolve(ecDir, 'index.simple.js'), esmDir);

            await transformDistributionFiles(nodePath.resolve(ecDir, esmDir), esmDir);
            await transformDistributionFiles(nodePath.resolve(ecDir, 'types'), esmDir);
            fsExtra.removeSync(tmpDir);
        }
    },
    {
        logLabel: 'extension ts -> js-esm',
        compilerOptionsOverride: {
            module: 'ES2015',
            rootDir: extensionSrcDir,
            outDir: extensionESMDir
        },
        srcGlobby: extensionSrcGlobby,
        transformOptions: {
            filesGlobby: {patterns: ['**/*.js'], cwd: extensionESMDir},
            preamble: preamble.js,
            transformDEV: true
        },
        before: async function () {
            fsExtra.removeSync(extensionESMDir);
        },
        after: async function () {
            await transformDistributionFiles(extensionESMDir, 'lib');
        }
    }
];



/**
 * @public
 */
module.exports = async function () {

    for (let {
        logLabel, compilerOptionsOverride, srcGlobby,
        transformOptions, before, after
    } of compileWorkList) {

        process.stdout.write(chalk.green.dim(`[${logLabel}]: compiling ...`));

        before && await before();

        let srcPathList = await readFilePaths(srcGlobby);

        await tsCompile(compilerOptionsOverride, srcPathList);

        process.stdout.write(chalk.green.dim(` done \n`));

        process.stdout.write(chalk.green.dim(`[${logLabel}]: transforming ...`));

        await transformCode(transformOptions);

        after && await after();

        process.stdout.write(chalk.green.dim(` done \n`));
    }

    process.stdout.write(chalk.green.dim(`Generating entries ...`));
    generateEntries();
    process.stdout.write(chalk.green.dim(`Bundling DTS ...`));
    await bundleDTS();

    console.log(chalk.green.dim('All done.'));
};

async function runTsCompile(localTs, compilerOptions, srcPathList) {
    // Must do it. becuase the value in tsconfig.json might be different from the inner representation.
    // For example: moduleResolution: "NODE" => moduleResolution: 2
    const {options, errors} = localTs.convertCompilerOptionsFromJson(compilerOptions, ecDir);

    if (errors.length) {
        let errMsg = 'tsconfig parse failed: '
            + errors.map(error => error.messageText).join('. ')
            + '\n compilerOptions: \n' + JSON.stringify(compilerOptions, null, 4);
        assert(false, errMsg);
    }

    // See: https://github.com/microsoft/TypeScript/wiki/Using-the-Compiler-API

    let program = localTs.createProgram(srcPathList, options);
    let emitResult = program.emit();

    let allDiagnostics = localTs
        .getPreEmitDiagnostics(program)
        .concat(emitResult.diagnostics);

    allDiagnostics.forEach(diagnostic => {
        if (diagnostic.file) {
            let {line, character} = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start);
            let message = localTs.flattenDiagnosticMessageText(diagnostic.messageText, '\n');
            console.log(chalk.red(`${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`));
        }
        else {
            console.log(chalk.red(localTs.flattenDiagnosticMessageText(diagnostic.messageText, '\n')));
        }
    });
    if (allDiagnostics.length > 0) {
        throw new Error('TypeScript Compile Failed')
    }
}
module.exports.runTsCompile = runTsCompile;

async function tsCompile(compilerOptionsOverride, srcPathList) {
    assert(
        compilerOptionsOverride
        && compilerOptionsOverride.module
        && compilerOptionsOverride.rootDir
        && compilerOptionsOverride.outDir
    );

    let compilerOptions = {
        ...tsConfig.compilerOptions,
        ...compilerOptionsOverride,
        sourceMap: false
    };

    runTsCompile(ts, compilerOptions, srcPathList);
}

/**
 * Transform import/require path in the entry file to `esm` or `lib`.
 */
function transformRootFolderInEntry(entryFile, replacement) {
    let code = fs.readFileSync(entryFile, 'utf-8');
    // Simple regex replacement
    // TODO More robust way?
    assert(
        !/(import\s+|from\s+|require\(\s*)["']\.\/echarts\./.test(code)
        && !/(import\s+|from\s+|require\(\s*)["']echarts\./.test(code),
        'Import echarts.xxx.ts is not supported.'
    );
    code = code.replace(/((import\s+|from\s+|require\(\s*)["'])\.\//g, `$1./${replacement}/`);
    fs.writeFileSync(
        entryFile,
        // Also transform zrender.
        singleTransformZRRootFolder(code, replacement),
        'utf-8'
    );
}

/**
 * Transform `zrender/src` to `zrender/esm` in all files
 */
async function transformDistributionFiles(rooltFolder, replacement) {
    const files = await readFilePaths({
        patterns: ['**/*.js', '**/*.d.ts'],
        cwd: rooltFolder
    });
    // Simple regex replacement
    // TODO More robust way?
    for (let fileName of files) {
        let code = fs.readFileSync(fileName, 'utf-8');
        code = singleTransformZRRootFolder(code, replacement);
        // For lower ts version, not use import type
        // TODO Use https://github.com/sandersn/downlevel-dts ?
        // if (fileName.endsWith('.d.ts')) {
        //     code = singleTransformImportType(code);
        // }
        fs.writeFileSync(fileName, code, 'utf-8');
    }
}

function singleTransformZRRootFolder(code, replacement) {
    return code.replace(/([\"\'])zrender\/src\//g, `$1zrender/${replacement}/`);
}

// function singleTransformImportType(code) {
//     return code.replace(/import\s+type\s+/g, 'import ');
// }

/**
 * @param {Object} transformOptions
 * @param {Object} transformOptions.filesGlobby {patterns: string[], cwd: string}
 * @param {string} [transformOptions.preamble] See './preamble.js'
 * @param {boolean} [transformOptions.transformDEV]
 */
async function transformCode({filesGlobby, preamble, transformDEV}) {

    let filePaths = await readFilePaths(filesGlobby);

    filePaths.map(filePath => {
        let code = fs.readFileSync(filePath, 'utf8');

        if (transformDEV) {
            let result = transformDEVUtil.transform(code, false);
            code = result.code;
        }

        code = autoGeneratedFileAlert + code;

        if (preamble) {
            code = preamble + code;
        }

        fs.writeFileSync(filePath, code, 'utf8');
    });
}

async function readFilePaths({patterns, cwd}) {
    assert(patterns && cwd);
    return (
        await globby(patterns, {cwd})
    ).map(
        srcPath => nodePath.resolve(cwd, srcPath)
    );
}

async function bundleDTS() {

    const outDir = nodePath.resolve(__dirname, '../types/dist');
    const commonConfig = {
        onwarn(warning, rollupWarn) {
            // Not warn circular dependency
            if (warning.code !== 'CIRCULAR_DEPENDENCY') {
                rollupWarn(warning);
            }
        },
        plugins: [
            dts({
                respectExternal: true
            })
//             {
//                 generateBundle(options, bundle) {
//                     for (let chunk of Object.values(bundle)) {
//                         chunk.code = `
// type Omit<T, K> = Pick<T, Exclude<keyof T, K>>;
// ${chunk.code}`
//                     }
//                 }
//             }
        ]
    };

    // Bundle chunks.
    const parts = [
        'core', 'charts', 'components', 'renderers', 'option'
    ];
    const inputs = {};
    parts.forEach(partName => {
        inputs[partName] = nodePath.resolve(__dirname, `../types/src/export/${partName}.d.ts`)
    });

    const bundle = await rollup.rollup({
        input: inputs,
        ...commonConfig
    });
    let idx = 1;
    await bundle.write({
        dir: outDir,
        minifyInternalExports: false,
        manualChunks: (id) => {
            // Only create one chunk.
            return 'shared';
        },
        chunkFileNames: 'shared.d.ts'
    });

    // Bundle all in one
    const bundleAllInOne = await rollup.rollup({
        input: nodePath.resolve(__dirname, `../types/src/export/all.d.ts`),
        ...commonConfig
    });
    await bundleAllInOne.write({
        file: nodePath.resolve(outDir, 'echarts.d.ts')
    });
}

function readTSConfig() {
    // tsconfig.json may have comment string, which is invalid if
    // using `require('tsconfig.json'). So we use a loose parser.
    let filePath = nodePath.resolve(ecDir, 'tsconfig.json');
    const tsConfigText = fs.readFileSync(filePath, {encoding: 'utf8'});
    return (new Function(`return ( ${tsConfigText} )`))();
}


function generateEntries() {
    ['charts', 'components', 'renderers', 'core'].forEach(entryName => {
        if (entryName !== 'option') {
            const jsCode = fs.readFileSync(nodePath.join(__dirname, `template/${entryName}.js`), 'utf-8');
            fs.writeFileSync(nodePath.join(__dirname, `../${entryName}.js`), jsCode, 'utf-8');
        }

        const dtsCode = fs.readFileSync(nodePath.join(__dirname, `/template/${entryName}.d.ts`), 'utf-8');
        fs.writeFileSync(nodePath.join(__dirname, `../${entryName}.d.ts`), dtsCode, 'utf-8');
    });
}

module.exports.readTSConfig = readTSConfig;
