"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.BackendCompilation = void 0;
//#region imports
const lib_1 = require("tnp-core/lib");
const lib_2 = require("tnp-core/lib");
const lib_3 = require("tnp-helpers/lib");
const constants_1 = require("../../../../../../../constants");
const dev_mode_models_1 = require("../../../../../taon-worker/dev-mode/dev-mode.models");
//#endregion
class BackendCompilation {
    buildOptions;
    project;
    taonBuildObserver;
    //#region static
    static counter = 1;
    //#endregion
    //#region fields & getters
    isEnableCompilation = true;
    compilerName = 'Backend Compiler';
    //#endregion
    //#region constructor
    //#region @backend
    constructor(buildOptions, project, taonBuildObserver) {
        this.buildOptions = buildOptions;
        this.project = project;
        this.taonBuildObserver = taonBuildObserver;
    }
    //#endregion
    //#endregion
    async runTask() {
        //#region @backendFunc
        const outDistPath = this.project.pathFor(constants_1.distMainProject);
        // Helpers.System.Operations.tryRemoveDir(outDistPath)
        try {
            lib_2.fse.unlinkSync(outDistPath);
        }
        catch (error) { }
        if (!lib_2.fse.existsSync(outDistPath)) {
            lib_2.fse.mkdirpSync(outDistPath);
        }
        await this.libCompilation(this.buildOptions, {
            generateDeclarations: true,
        });
        //#endregion
    }
    //#region methods / lib compilation
    async libCompilation(buildOptions, { generateDeclarations = false, tsExe = 'npm-run tsc', diagnostics = false, }) {
        //#region @backendFunc
        const watch = buildOptions.build.watch && !this.project.watcher.isTaonLightWatcherMode;
        if (!this.isEnableCompilation) {
            lib_3.Helpers.log(`Compilation disabled for ${lib_2._.startCase(BackendCompilation.name)}`);
            return;
        }
        const paramasCommon = {
            watch: watch ? ' -w ' : '',
            outDir: ` --outDir ${constants_1.distMainProject + (buildOptions.build.prod ? constants_1.prodSuffix : '')} `,
            noEmitOnError: !watch ? ' --noEmitOnError true ' : '',
            extendedDiagnostics: diagnostics ? ' --extendedDiagnostics ' : '',
            preserveWatchOutput: ` --preserveWatchOutput `,
        };
        const tsconfigBackendPath = (0, lib_2.crossPlatformPath)(this.project.pathFor(buildOptions.build.prod
            ? constants_1.tsconfigBackendDistJson_PROD
            : constants_1.tsconfigBackendDistJson));
        let nocutsrcFolder = this.project.pathFor(constants_1.distNoCutSrcMainProject + (buildOptions.build.prod ? constants_1.prodSuffix : ''));
        const paramsJS = {
            mapRoot: ` --mapRoot ${nocutsrcFolder} `,
            project: `--project ${tsconfigBackendPath}`,
            ...paramasCommon,
        };
        const paramsMaps = { ...paramasCommon };
        paramsMaps.outDir = ` --outDir ${nocutsrcFolder}`;
        paramsMaps.noEmitOnError = !watch ? ' --noEmitOnError false ' : '';
        const commandJs = `${tsExe} ${Object.values(paramsJS).join(' ')}  `;
        const commandMaps = `${tsExe} ${Object.values(paramsMaps).join(' ')} `;
        delete paramsJS.outDir;
        const commandJsEsm = `${tsExe} ${Object.values(paramsJS).join(' ').replace('.backend.', '.backend-esm.')}  `;
        const taonActionFromParentName = lib_1.GlobalStorage.get(lib_1.taonActionFromParent);
        lib_3.Helpers.getIsVerboseMode() &&
            console.log({
                commandJs,
                commandMaps,
                commandJsEsm,
            });
        lib_3.Helpers.info(`

    [compilation-backend] Starting (${buildOptions.build.watch ? 'watch' : 'normal'}) backend TypeScript build....

    `);
        const cwd = this.project.location;
        await this.project.nodeModules.makeSureInstalled();
        //#region output line replace
        const additionalReplace = (line) => {
            // nothing to replace for now
            if (taonActionFromParentName && line.includes('./src/')) {
                line = line.replace('./src/', `./${taonActionFromParentName}/src/`);
            }
            if (line.includes('../src/lib/')) {
                line = line.replace('../src/lib/', './src/lib/');
            }
            return line;
        };
        const outputLineReplace = (line) => {
            //#region outputs replacement
            if (line.startsWith(`${constants_1.tmpSourceDist + constants_1.prodSuffix}/`)) {
                return additionalReplace(line.replace(`${constants_1.tmpSourceDist + constants_1.prodSuffix}/`, `./${constants_1.srcMainProject}/`));
            }
            if (line.startsWith(`${constants_1.tmpSourceDist}/`)) {
                return additionalReplace(line.replace(`${constants_1.tmpSourceDist}/`, `./${constants_1.srcMainProject}/`));
            }
            return additionalReplace(line
                .replace(`../${constants_1.tmpSourceDist + constants_1.prodSuffix}/`, `./${constants_1.srcMainProject}/`)
                .replace(`../${constants_1.tmpSourceDist}/`, `./${constants_1.srcMainProject}/`));
            //#endregion
        };
        //#endregion
        //#region compilation commonjs backend
        await (0, lib_1.startAsync)(commandJs, cwd, {
            uniqueName: 'tsc cjs',
            prefix: true,
            similarProcessKey: 'tsc',
            resolvePromiseMsgCallback_anystd: () => {
                if (this.project.watcher.isTaonLightWatcherMode) {
                    this.taonBuildObserver.backendCjsState.set(dev_mode_models_1.DevMode.ProjectBuildStatus.DONE_BUILDING_SUCCESS);
                }
            },
            onExitCallback: async (code, resolve, reject) => this.project.framework.handlExitError(buildOptions, code, resolve, reject, 'backend-cjs', `Typescript compilation (backend commonjs) error`),
            outputLineReplace: (line) => outputLineReplace(line),
            resolvePromiseMsg_stdout: [constants_1.COMPILATION_COMPLETE_TSC],
            rebuildOnChange: this.project.watcher.rebuildTriggerWatcher('backend-cjs'),
        });
        //#endregion
        lib_3.Helpers.logInfo(`* Typescript compilation first part done (cjs)`);
        await this.project.nodeModules.makeSureInstalled();
        //#region compilation esm backend
        if (!buildOptions.build.prod) {
            // in prod normal build is esm - not need for this
            await (0, lib_1.startAsync)(commandJsEsm, cwd, {
                uniqueName: 'tsc esm',
                prefix: true,
                similarProcessKey: 'tsc',
                resolvePromiseMsgCallback_anystd: () => {
                    if (this.project.watcher.isTaonLightWatcherMode) {
                        this.taonBuildObserver.backendEsmState.set(dev_mode_models_1.DevMode.ProjectBuildStatus.DONE_BUILDING_SUCCESS);
                    }
                },
                onExitCallback: async (code, resolve, reject) => this.project.framework.handlExitError(buildOptions, code, resolve, reject, 'backend-esm', `Typescript compilation (backend esm) error`),
                outputLineReplace: (line) => outputLineReplace(line),
                resolvePromiseMsg_stdout: [constants_1.COMPILATION_COMPLETE_TSC],
                rebuildOnChange: this.project.watcher.rebuildTriggerWatcher('backend-esm'),
            });
        }
        //#endregion
        lib_3.Helpers.logInfo(`* Typescript compilation second part done (esm)`);
        await this.project.nodeModules.makeSureInstalled();
        //#region compilation js maps backend
        await (0, lib_1.startAsync)(commandMaps, cwd, {
            uniqueName: 'tsc js maps',
            similarProcessKey: 'tsc',
            prefix: true,
            hideOutput_stderr: true,
            hideOutput_stdout: true,
            resolvePromiseMsgCallback_anystd: () => {
                if (this.project.watcher.isTaonLightWatcherMode) {
                    this.taonBuildObserver.backendJsMapsState.set(dev_mode_models_1.DevMode.ProjectBuildStatus.DONE_BUILDING_SUCCESS);
                }
            },
            onExitCallback: async (code, resolve, reject) => {
                resolve(); // TODO this is throwing tsocnfig errpr
            },
            resolvePromiseMsg_stdout: [constants_1.COMPILATION_WATCHING_STARTED],
            rebuildOnChange: this.project.watcher.rebuildTriggerWatcher('backend-js-maps'),
        });
        //#endregion
        lib_3.Helpers.logInfo(`* Typescript compilation thrid part done (js maps)`);
        lib_3.Helpers.info(`

    Backend TypeScript build done....

        `);
        if (buildOptions.build.watch) {
            // console.log(Helpers.terminalLine());
            lib_3.Helpers.info(`

    ${lib_2.chalk.bold('YOU CAN ATTACH YOUR CODE DEBUGGER NOW')}

    `);
            // console.log(Helpers.terminalLine());
        }
        //#endregion
    }
}
exports.BackendCompilation = BackendCompilation;
//# sourceMappingURL=compilation-backend.js.map