// src/eventcatalog-config-file-utils.js
import { readFile, writeFile, rm, copyFile, mkdtemp, symlink } from "fs/promises";
import { existsSync } from "fs";
import path from "path";
import { v4 as uuidV4 } from "uuid";
import { pathToFileURL } from "url";
import { tmpdir } from "os";
import matter from "gray-matter";
async function cleanup(projectDirectory) {
  const filePath = path.join(projectDirectory, "eventcatalog.config.mjs");
  if (existsSync(filePath)) {
    await rm(filePath);
  }
}
var findNodeModulesDirectory = (directory) => {
  let currentDirectory = directory;
  while (true) {
    const nodeModulesDirectory = path.join(currentDirectory, "node_modules");
    if (existsSync(nodeModulesDirectory)) {
      return nodeModulesDirectory;
    }
    const parentDirectory = path.dirname(currentDirectory);
    if (parentDirectory === currentDirectory) {
      return void 0;
    }
    currentDirectory = parentDirectory;
  }
};
var linkNodeModulesIntoTempDirectory = async ({ projectDirectory, tempDir }) => {
  const nodeModulesDirectory = findNodeModulesDirectory(projectDirectory);
  if (!nodeModulesDirectory) {
    return;
  }
  await symlink(nodeModulesDirectory, path.join(tempDir, "node_modules"), "dir");
};
var createTemporaryConfigDirectory = async (projectDirectory) => {
  const nodeModulesDirectory = findNodeModulesDirectory(projectDirectory);
  if (nodeModulesDirectory) {
    return mkdtemp(path.join(nodeModulesDirectory, ".eventcatalog-config-"));
  }
  const tempDir = await mkdtemp(path.join(tmpdir(), "eventcatalog-config-"));
  await linkNodeModulesIntoTempDirectory({ projectDirectory, tempDir });
  return tempDir;
};
var getEventCatalogConfigFile = async (projectDirectory) => {
  let tempDir;
  try {
    let configFilePath = path.join(projectDirectory, "eventcatalog.config.js");
    const filePath = path.join(projectDirectory, "package.json");
    const packageJson = JSON.parse(await readFile(filePath, "utf-8"));
    if (packageJson?.type !== "module") {
      tempDir = await createTemporaryConfigDirectory(projectDirectory);
      configFilePath = path.join(tempDir, "eventcatalog.config.mjs");
      await copyFile(path.join(projectDirectory, "eventcatalog.config.js"), configFilePath);
    }
    const configFileURL = `${pathToFileURL(configFilePath).href}?t=${Date.now()}`;
    const config = await import(
      /* @vite-ignore */
      configFileURL
    );
    return config.default;
  } finally {
    await cleanup(projectDirectory);
    if (tempDir) {
      await rm(tempDir, { recursive: true, force: true });
    }
  }
};
var writeEventCatalogConfigFile = async (projectDirectory, newConfig) => {
  try {
    const configFilePath = path.join(projectDirectory, "eventcatalog.config.js");
    let content = await readFile(configFilePath, "utf8");
    const startIndex = content.indexOf("export default {");
    if (startIndex === -1) {
      return;
    }
    Object.entries(newConfig).forEach(([key, value]) => {
      const valueString = JSON.stringify(value, null, 2).replace(/"/g, "'").replace(/\n/g, "\n  ");
      const keyRegex = new RegExp(`(${key}\\s*:)([^,}]+)`, "g");
      if (content.match(keyRegex)) {
        content = content.replace(keyRegex, `$1 ${valueString}`);
      } else {
        const insertPosition = content.indexOf("{", startIndex) + 1;
        content = content.slice(0, insertPosition) + `
  ${key}: ${valueString},` + content.slice(insertPosition);
      }
    });
    await writeFile(configFilePath, content);
  } finally {
    await cleanup(projectDirectory);
  }
};
var verifyRequiredFieldsAreInCatalogConfigFile = async (projectDirectory) => {
  try {
    const config = await getEventCatalogConfigFile(projectDirectory);
    if (!config.cId) {
      await writeEventCatalogConfigFile(projectDirectory, { cId: uuidV4() });
    }
  } catch (error) {
  }
};
function addPropertyToFrontMatter(input, newProperty, newValue) {
  const file = matter(input);
  return matter.stringify(file.content, { ...file.data, [newProperty]: newValue });
}

export {
  cleanup,
  getEventCatalogConfigFile,
  writeEventCatalogConfigFile,
  verifyRequiredFieldsAreInCatalogConfigFile,
  addPropertyToFrontMatter
};
