import { createRequire } from "module";
import os from "os";
import path from "path";
import invariant from "tiny-invariant";
import { fileURLToPath } from "url";
import { parentPort } from "worker_threads";
import { Checker } from "../../Checker.js";
import {
  consoleLog,
  diagnosticToRuntimeError,
  diagnosticToTerminalLog,
  ensureCall,
  normalizeVueTscDiagnostic,
  toClientPayload,
  wrapCheckerSummary
} from "../../logger.js";
import { ACTION_TYPES } from "../../types.js";
import { prepareVueTsc } from "./prepareVueTsc.js";
const _require = createRequire(import.meta.url);
const __filename = fileURLToPath(import.meta.url);
let createServeAndBuild;
const createDiagnostic = (pluginConfig) => {
  let overlay = true;
  let terminal = true;
  let currDiagnostics = [];
  return {
    config: ({ enableOverlay, enableTerminal }) => {
      overlay = enableOverlay;
      terminal = enableTerminal;
    },
    async configureServer({ root }) {
      invariant(pluginConfig.vueTsc, "config.vueTsc should be `false`");
      const { targetTsDir } = await prepareVueTsc();
      const vueTs = _require(path.resolve(targetTsDir, "lib/typescript.js"));
      const finalConfig = pluginConfig.vueTsc === true ? { root, tsconfigPath: "tsconfig.json" } : {
        root: pluginConfig.vueTsc.root ?? root,
        tsconfigPath: pluginConfig.vueTsc.tsconfigPath ?? "tsconfig.json"
      };
      let configFile;
      configFile = vueTs.findConfigFile(
        finalConfig.root,
        vueTs.sys.fileExists,
        finalConfig.tsconfigPath
      );
      if (configFile === void 0) {
        throw Error(
          `Failed to find a valid tsconfig.json: ${finalConfig.tsconfigPath} at ${finalConfig.root} is not a valid tsconfig`
        );
      }
      let logChunk = "";
      let prevLogChunk = "";
      const reportDiagnostic = (diagnostic) => {
        const normalizedDiagnostic = normalizeVueTscDiagnostic(diagnostic);
        if (normalizedDiagnostic === null) {
          return;
        }
        currDiagnostics.push(diagnosticToRuntimeError(normalizedDiagnostic));
        logChunk += os.EOL + diagnosticToTerminalLog(normalizedDiagnostic, "vue-tsc");
      };
      const reportWatchStatusChanged = (diagnostic, newLine, options, errorCount) => {
        var _a;
        if (diagnostic.code === 6031)
          return;
        switch (diagnostic.code) {
          case 6031:
          case 6032:
            logChunk = "";
            currDiagnostics = [];
            return;
          case 6193:
          case 6194:
            if (overlay) {
              (_a = parentPort) == null ? void 0 : _a.postMessage({
                type: ACTION_TYPES.overlayError,
                payload: toClientPayload("vue-tsc", currDiagnostics)
              });
            }
        }
        ensureCall(() => {
          if (errorCount === 0) {
            logChunk = "";
          }
          if (terminal) {
            logChunk = logChunk + os.EOL + wrapCheckerSummary("vue-tsc", diagnostic.messageText.toString());
            if (logChunk === prevLogChunk) {
              return;
            }
            prevLogChunk = logChunk;
            consoleLog(logChunk);
          }
        });
      };
      const createProgram = vueTs.createSemanticDiagnosticsBuilderProgram;
      const host = vueTs.createWatchCompilerHost(
        configFile,
        { noEmit: true },
        vueTs.sys,
        createProgram,
        reportDiagnostic,
        reportWatchStatusChanged
      );
      vueTs.createWatchProgram(host);
    }
  };
};
class VueTscChecker extends Checker {
  constructor() {
    super({
      name: "vueTsc",
      absFilePath: __filename,
      build: {
        buildBin: (config) => {
          if (typeof config.vueTsc === "object") {
            const { root = "", tsconfigPath = "" } = config.vueTsc;
            let args = ["--noEmit"];
            let projectPath = "";
            if (root || tsconfigPath) {
              projectPath = root ? path.join(root, tsconfigPath) : tsconfigPath;
            }
            if (projectPath) {
              args.push("-p", projectPath);
            }
            return ["vue-tsc", args];
          }
          return ["vue-tsc", ["--noEmit"]];
        }
      },
      createDiagnostic
    });
  }
  init() {
    const _createServeAndBuild = super.initMainThread();
    createServeAndBuild = _createServeAndBuild;
    super.initWorkerThread();
  }
}
const tscChecker = new VueTscChecker();
tscChecker.prepare();
tscChecker.init();
export {
  VueTscChecker,
  createServeAndBuild
};
//# sourceMappingURL=main.js.map