import path from "node:path";
import { fileURLToPath, pathToFileURL } from "node:url";
import { bold, cyan, underline } from "kleur/colors";
import { loadTSConfig } from "../core/config/tsconfig.js";
import { appendForwardSlash } from "../core/path.js";
import { createContentTypesGenerator } from "./types-generator.js";
import { getContentPaths, globalContentConfigObserver } from "./utils.js";
async function attachContentServerListeners({
  viteServer,
  fs,
  logger,
  settings
}) {
  const contentPaths = getContentPaths(settings.config, fs);
  if (fs.existsSync(contentPaths.contentDir)) {
    logger.debug(
      "content",
      `Watching ${cyan(
        contentPaths.contentDir.href.replace(settings.config.root.href, "")
      )} for changes`
    );
    const maybeTsConfigStats = await getTSConfigStatsWhenAllowJsFalse({ contentPaths, settings });
    if (maybeTsConfigStats) warnAllowJsIsFalse({ ...maybeTsConfigStats, logger });
    await attachListeners();
  } else {
    viteServer.watcher.on("addDir", contentDirListener);
    async function contentDirListener(dir) {
      if (appendForwardSlash(pathToFileURL(dir).href) === contentPaths.contentDir.href) {
        logger.debug("content", `Content directory found. Watching for changes`);
        await attachListeners();
        viteServer.watcher.removeListener("addDir", contentDirListener);
      }
    }
  }
  async function attachListeners() {
    const contentGenerator = await createContentTypesGenerator({
      fs,
      settings,
      logger,
      viteServer,
      contentConfigObserver: globalContentConfigObserver
    });
    await contentGenerator.init();
    logger.debug("content", "Types generated");
    viteServer.watcher.on("add", (entry) => {
      contentGenerator.queueEvent({ name: "add", entry });
    });
    viteServer.watcher.on(
      "addDir",
      (entry) => contentGenerator.queueEvent({ name: "addDir", entry })
    );
    viteServer.watcher.on(
      "change",
      (entry) => contentGenerator.queueEvent({ name: "change", entry })
    );
    viteServer.watcher.on("unlink", (entry) => {
      contentGenerator.queueEvent({ name: "unlink", entry });
    });
    viteServer.watcher.on(
      "unlinkDir",
      (entry) => contentGenerator.queueEvent({ name: "unlinkDir", entry })
    );
  }
}
function warnAllowJsIsFalse({
  logger,
  tsConfigFileName,
  contentConfigFileName
}) {
  logger.warn(
    "content",
    `Make sure you have the ${bold("allowJs")} compiler option set to ${bold(
      "true"
    )} in your ${bold(tsConfigFileName)} file to have autocompletion in your ${bold(
      contentConfigFileName
    )} file. See ${underline(
      cyan("https://www.typescriptlang.org/tsconfig#allowJs")
    )} for more information.`
  );
}
async function getTSConfigStatsWhenAllowJsFalse({
  contentPaths,
  settings
}) {
  const isContentConfigJsFile = [".js", ".mjs"].some(
    (ext) => contentPaths.config.url.pathname.endsWith(ext)
  );
  if (!isContentConfigJsFile) return;
  const inputConfig = await loadTSConfig(fileURLToPath(settings.config.root));
  if (typeof inputConfig === "string") return;
  const tsConfigFileName = inputConfig.tsconfigFile.split(path.sep).pop();
  if (!tsConfigFileName) return;
  const contentConfigFileName = contentPaths.config.url.pathname.split(path.sep).pop();
  const allowJSOption = inputConfig.tsconfig.compilerOptions?.allowJs;
  if (allowJSOption) return;
  return { tsConfigFileName, contentConfigFileName };
}
export {
  attachContentServerListeners
};
