import { describe, it, expect } from "vitest";
import { readdirSync, readFileSync } from "node:fs";
import { join } from "node:path";

// ── Registratiebewaking van de barrel-indexen ────────────────────────────────
// De barrels (onderdelen/index.ts en modellen/index.ts) worden gegenereerd
// door scripts/genereer-barrels.mjs, dat automatisch draait vóór elke
// dev/test/poort/build-run (pre-hooks in package.json). Deze test blijft als
// vangnet voor runs die de generator omzeilen (bv. een losse vitest-aanroep
// vanuit een editor): een themabestand dat wél in de map staat maar níét in
// de barrel is geïmporteerd, ontbreekt stilzwijgend in de bibliotheek — geen
// compile-fout, geen runtime-fout, de clausules zijn gewoon weg. Elk
// .ts-bestand in de map (behalve de index zelf en tests) moet in de barrel
// voorkomen.
//
// N.B. "geïmporteerd maar spread vergeten" wordt al gedekt door eslint
// (no-unused-vars op de ongebruikte import) — de poort is stil, dus dat kan
// niet ongemerkt passeren.

const WORTEL = join(process.cwd(), "data", "modeldocumenten");

function bestandenIn(map: string): string[] {
  return readdirSync(join(WORTEL, map))
    .filter((f) => f.endsWith(".ts"))
    .filter((f) => f !== "index.ts" && !f.endsWith(".test.ts"))
    .map((f) => f.replace(/\.ts$/, ""));
}

function geimporteerdIn(map: string): Set<string> {
  const bron = readFileSync(join(WORTEL, map, "index.ts"), "utf-8");
  return new Set(
    [...bron.matchAll(/from\s+"\.\/([^"]+)"/g)].map((m) => m[1])
  );
}

describe.each(["onderdelen", "modellen"] as const)(
  "barrel-registratie — %s",
  (map) => {
    it("elk themabestand in de map is geïmporteerd in index.ts", () => {
      const geimporteerd = geimporteerdIn(map);
      const ontbrekend = bestandenIn(map).filter((f) => !geimporteerd.has(f));
      expect(
        ontbrekend,
        `Deze bestanden in data/modeldocumenten/${map}/ staan niet in de barrel ` +
          `(index.ts) en ontbreken dus stilzwijgend in de seed-bibliotheek — ` +
          `voeg de import + spread toe`
      ).toEqual([]);
    });
  }
);
