import { writeFileSync } from "node:fs";
import { dirname, relative, resolve } from "node:path";
import { fileURLToPath } from "node:url";
import { walkDir } from "./utils.mjs";

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);

const docFiles = [];
const nsDocFiles = [];
const docImagesFiles = [];
const docRoot = resolve(__dirname, "../../src/Documentation/doc");
const markdownRoot = resolve(__dirname, "../../markdown");
const docImagesRoot = resolve(__dirname, "../../src/Documentation/images");

function addFileToListOfDocPages(files, root, filePath) {
  if (filePath.endsWith(".DS_Store")) {
    return;
  }
  // Windows path uses "\", so we need to replace it with "/".
  files.push(relative(root, filePath).replace(/\\/g, "/"));
}

function processDir(dir) {
  walkDir(dir, (filePath) => {
    if (filePath.startsWith(docRoot)) {
      addFileToListOfDocPages(docFiles, docRoot, filePath);
    } else if (filePath.startsWith(markdownRoot)) {
      addFileToListOfDocPages(nsDocFiles, markdownRoot, filePath);
    } else {
      addFileToListOfDocPages(docImagesFiles, docImagesRoot, filePath);
    }
  });
}

processDir(docRoot);
processDir(markdownRoot);
processDir(docImagesRoot);

/**
 * When importing NS API markdown files, we use "nsDoc_something" instead of file<number> like other docs. Currently,
 * there are more than 1400 files in the "markdown" folder. If we use the file<number> pattern, every time we add or
 * remove a file, it creates a massive diff change. For example, let's say it looks like this:
 *
 * import file100 from "../../markdown/bitburner.activefragment.highestcharge.md?raw";
 * import file101 from "../../markdown/bitburner.activefragment.id.md?raw";
 * ...
 * import file1500 from "../../markdown/index.md?raw";
 *
 * If we delete "bitburner.activefragment.id.md", all lines below "import file100 ..." will be changed. In this case,
 * the maintainer has to either check all of those lines, which is a meticulous task, or ignore them and hope that
 * nothing goes wrong.
 *
 * By using the nsDoc_something pattern, we don't have this problem. Until now, we also have had this problem with docs
 * in src\Documentation\doc, but we rarely add or remove files in it, so it's not a big deal. Checking ~60 lines is also
 * much easier than checking ~1400 lines.
 */
const autogeneratedContent = `// THIS FILE IS AUTOGENERATED. DO NOT EDIT IT MANUALLY.
${docFiles.map((f, i) => `import file${i} from "./doc/${f}?raw";\n`).join("")}
${nsDocFiles.map((f) => `import nsDoc_${f.replaceAll(".", "_")} from "../../markdown/${f}?raw";\n`).join("")}
${docImagesFiles.map((f) => `import docImages_${f.replaceAll(/\.|-/g, "_")} from "./images/${f}";\n`).join("")}
export const AllPages: Record<string, string> = {};
${docFiles.map((f, i) => `AllPages["${f}"] = file${i};\n`).join("")}
${nsDocFiles.map((f) => `AllPages["nsDoc/${f}"] = nsDoc_${f.replaceAll(".", "_")};\n`).join("")}
export const nsApiPages = Object.keys(AllPages)
  .filter((page) => page.startsWith("nsDoc"))
  .map((page) => page.replace("nsDoc/", ""));

export const DocImages: Record<string, string> = {};
${docImagesFiles.map((f) => `DocImages["${f}"] = docImages_${f.replaceAll(/\.|-/g, "_")};\n`).join("")}`;

writeFileSync(resolve(__dirname, "../../src/Documentation/pages.ts"), autogeneratedContent, { encoding: "utf-8" });
