"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.VueTscChecker = void 0;
const os_1 = __importDefault(require("os"));
const path_1 = __importDefault(require("path"));
const tiny_invariant_1 = __importDefault(require("tiny-invariant"));
const worker_threads_1 = require("worker_threads");
const Checker_1 = require("../../Checker");
const logger_1 = require("../../logger");
const types_1 = require("../../types");
const prepareVueTsc_1 = require("./prepareVueTsc");
const createDiagnostic = (pluginConfig) => {
    let overlay = true;
    let terminal = true;
    let currDiagnostics = [];
    return {
        config: ({ enableOverlay, enableTerminal }) => {
            overlay = enableOverlay;
            terminal = enableTerminal;
        },
        configureServer({ root }) {
            var _a, _b;
            (0, tiny_invariant_1.default)(pluginConfig.vueTsc, 'config.vueTsc should be `false`');
            const { tsDirTo } = (0, prepareVueTsc_1.prepareVueTsc)();
            const vueTs = require(path_1.default.resolve(tsDirTo, 'lib/tsc.js'));
            const finalConfig = pluginConfig.vueTsc === true
                ? { root, tsconfigPath: 'tsconfig.json' }
                : {
                    root: (_a = pluginConfig.vueTsc.root) !== null && _a !== void 0 ? _a : root,
                    tsconfigPath: (_b = pluginConfig.vueTsc.tsconfigPath) !== null && _b !== void 0 ? _b : 'tsconfig.json',
                };
            let configFile;
            configFile = vueTs.findConfigFile(finalConfig.root, vueTs.sys.fileExists, finalConfig.tsconfigPath);
            if (configFile === undefined) {
                throw Error(`Failed to find a valid tsconfig.json: ${finalConfig.tsconfigPath} at ${finalConfig.root} is not a valid tsconfig`);
            }
            let logChunk = '';
            // https://github.com/microsoft/TypeScript/blob/a545ab1ac2cb24ff3b1aaf0bfbfb62c499742ac2/src/compiler/watch.ts#L12-L28
            const reportDiagnostic = (diagnostic) => {
                const normalizedDiagnostic = (0, logger_1.normalizeVueTscDiagnostic)(diagnostic);
                if (normalizedDiagnostic === null) {
                    return;
                }
                currDiagnostics.push((0, logger_1.diagnosticToRuntimeError)(normalizedDiagnostic));
                logChunk += os_1.default.EOL + (0, logger_1.diagnosticToTerminalLog)(normalizedDiagnostic, 'vue-tsc');
            };
            const reportWatchStatusChanged = (diagnostic, newLine, options, errorCount
            // eslint-disable-next-line max-params
            ) => {
                if (diagnostic.code === 6031)
                    return;
                // https://github.com/microsoft/TypeScript/issues/32542
                // https://github.com/microsoft/TypeScript/blob/dc237b317ed4bbccd043ddda802ffde00362a387/src/compiler/diagnosticMessages.json#L4086-L4088
                switch (diagnostic.code) {
                    case 6031:
                    case 6032:
                        // clear current error and use the newer errors
                        logChunk = '';
                        // currErr = null
                        currDiagnostics = [];
                        return;
                    case 6193: // 1 Error
                    case 6194: // 0 errors or 2+ errors
                        if (overlay) {
                            worker_threads_1.parentPort === null || worker_threads_1.parentPort === void 0 ? void 0 : worker_threads_1.parentPort.postMessage({
                                type: types_1.ACTION_TYPES.overlayError,
                                payload: (0, logger_1.toViteCustomPayload)('vue-tsc', currDiagnostics),
                            });
                        }
                }
                (0, logger_1.ensureCall)(() => {
                    if (errorCount === 0) {
                        logChunk = '';
                    }
                    if (terminal) {
                        (0, logger_1.consoleLog)(logChunk + os_1.default.EOL + (0, logger_1.wrapCheckerSummary)('vue-tsc', diagnostic.messageText.toString()));
                    }
                });
            };
            // https://github.com/microsoft/TypeScript/issues/32385
            // https://github.com/microsoft/TypeScript/pull/33082/files
            const createProgram = vueTs.createSemanticDiagnosticsBuilderProgram;
            const host = vueTs.createWatchCompilerHost(configFile, { noEmit: true }, vueTs.sys, createProgram, reportDiagnostic, reportWatchStatusChanged);
            vueTs.createWatchProgram(host);
        },
    };
};
class VueTscChecker extends Checker_1.Checker {
    constructor() {
        super({
            name: 'vueTsc',
            absFilePath: __filename,
            build: {
                buildBin: (config) => {
                    if (typeof config.vueTsc === 'object') {
                        const { root, tsconfigPath } = config.vueTsc;
                        let args = ['--noEmit'];
                        // Custom config path
                        if (tsconfigPath) {
                            const fullConfigPath = root ? path_1.default.join(root, tsconfigPath) : tsconfigPath;
                            args = args.concat(['-p', fullConfigPath]);
                        }
                        return ['vue-tsc', args];
                    }
                    return ['vue-tsc', ['--noEmit']];
                },
            },
            createDiagnostic,
        });
    }
    init() {
        const createServeAndBuild = super.initMainThread();
        module.exports.createServeAndBuild = createServeAndBuild;
        super.initWorkerThread();
    }
}
exports.VueTscChecker = VueTscChecker;
const tscChecker = new VueTscChecker();
tscChecker.prepare();
tscChecker.init();
