import { expect, test } from "bun:test";
import { mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
import { join, resolve } from "node:path";

const root = resolve(import.meta.dir, "../../..");

test("per-process dev caches are excluded from root and example project tools", () => {
  const eslint = readFileSync(join(root, "eslint.config.js"), "utf8");
  const tsconfig = JSON.parse(readFileSync(join(root, "tsconfig.json"), "utf8")) as {
    exclude?: string[];
  };
  const prettier = readFileSync(join(root, ".prettierignore"), "utf8");

  expect(eslint).toContain('"**/.wrnexus-*/**"');
  expect(tsconfig.exclude).toContain("**/.wrnexus-*");
  expect(prettier).toContain("**/.wrnexus-*/**");

  const projects = ["basic-app", "inter-app-api-showcase"].map((name) =>
    join(root, "examples", name),
  );
  const caches = projects.map((project) => join(project, ".wrnexus-123"));

  for (const project of projects) {
    const projectEslint = readFileSync(join(project, "eslint.config.js"), "utf8");
    const projectTsconfig = JSON.parse(readFileSync(join(project, "tsconfig.json"), "utf8")) as {
      exclude?: string[];
    };
    const projectPrettier = readFileSync(join(project, ".prettierignore"), "utf8");

    expect(projectEslint).toContain('".wrnexus-*/**"');
    expect(projectEslint).toContain('"**/.wrnexus-*/**"');
    expect(projectTsconfig.exclude).toContain(".wrnexus-*");
    expect(projectTsconfig.exclude).toContain("**/.wrnexus-*");
    expect(projectPrettier).toContain(".wrnexus-*/");
    expect(projectPrettier).toContain("**/.wrnexus-*/");
  }

  for (const cache of caches) {
    mkdirSync(cache, { recursive: true });
    writeFileSync(join(cache, "broken.client.mjs"), "const = ;\n", "utf8");
    writeFileSync(join(cache, "broken.d.ts"), "type = ;\n", "utf8");
  }
  try {
    const lint = Bun.spawnSync(
      [
        "bunx",
        "eslint",
        "--no-warn-ignored",
        ...caches.flatMap((cache) => [
          join(cache, "broken.client.mjs"),
          join(cache, "broken.d.ts"),
        ]),
      ],
      { cwd: root },
    );
    expect(lint.exitCode).toBe(0);
  } finally {
    for (const cache of caches) rmSync(cache, { recursive: true, force: true });
  }
}, 15_000);
