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

const appRoot = process.cwd().endsWith(`${join("apps", "web")}`)
  ? process.cwd()
  : join(process.cwd(), "apps", "web");
const repoRoot = existsSync(join(process.cwd(), "turbo.json"))
  ? process.cwd()
  : join(appRoot, "..", "..");
const presentationRoots = [
  join(repoRoot, "packages", "ui", "src"),
  join(appRoot, "src", "App.tsx"),
  join(appRoot, "src", "app.css"),
  join(appRoot, "src", "lib", "ui-adapter"),
];

const forbiddenTerms = [
  "dimensionlab",
  "dimension lab",
  "vaultwarden",
  "forgejo",
  "grafana",
  "uptime kuma",
  "prometheus",
  "backrest",
  "open webui",
  "comfyui",
  "adminer",
  "cockpit",
  "ollama",
  "dimensionlab.net",
];

describe("presentation content boundary", () => {
  test("keeps environment-specific content out of route and UI implementation", () => {
    const source = withoutInternalPackageScope(
      presentationRoots.map(readPresentationSource).join("\n").toLowerCase(),
    );

    expect(forbiddenTerms.filter((term) => source.includes(term))).toEqual([]);
  });

  test("does not keep legacy presentation component files in the React runtime", () => {
    const legacyExtension = [".sve", "lte"].join("");

    expect(findFiles(join(appRoot, "src"), legacyExtension)).toEqual([]);
  });
});

function readPresentationSource(path: string): string {
  if (!existsSync(path)) return "";

  const stats = statSync(path);
  if (stats.isFile()) {
    if (path.endsWith(".test.ts")) return "";
    if (path.includes(`${join("packages", "ui", "src", "stories")}${"/"}`)) {
      return "";
    }
    if (!/\.(tsx|ts|js|mjs|css|json)$/.test(path)) return "";
    return readFileSync(path, "utf8");
  }

  return readdirSync(path)
    .map((entry) => readPresentationSource(join(path, entry)))
    .join("\n");
}

function findFiles(path: string, extension: string): string[] {
  const stats = statSync(path);
  if (stats.isFile()) return path.endsWith(extension) ? [path] : [];

  return readdirSync(path).flatMap((entry) => findFiles(join(path, entry), extension));
}

function withoutInternalPackageScope(source: string): string {
  return source
    .replaceAll("@dimensionlab/dashboard-model", "@internal/dashboard-model")
    .replaceAll("@dimensionlab/ui", "@internal/ui");
}
