import { test, expect } from "@playwright/test";

/**
 * Auth-Gating-Garantie (Definition of Done, oberstes Prinzip).
 *
 * NICHT in der Sandbox ausführbar (kein Server/DB) — deferred. Wird über
 * `npm run test:e2e:gating` gegen einen laufenden Server ausgeführt.
 *
 * Kerngarantie (Querschnittsstandard 1–3, default-deny dreifach):
 *  - Anonyme Aufrufe von Seiten -> Redirect auf /login (mit callbackUrl).
 *  - Anonyme Aufrufe von API-Routen -> 401 OHNE Daten-Leak.
 *  - Öffentliche Routen (Login, Health) bleiben erreichbar.
 *
 * Negativ-Probe (manuell/CI): Entfernen von `requireSession()` aus
 * `(app)/layout.tsx` muss diese Suite rot machen.
 */

// Geschützte Seiten (Redirect-Manifest). Neue Seiten hier ergänzen.
const PROTECTED_PAGES = [
  "/",
  "/start",
  "/fahrzeuge",
  "/fahrzeuge/00000000-0000-0000-0000-000000000001",
  "/geraete/00000000-0000-0000-0000-000000000002",
  "/wehren/00000000-0000-0000-0000-000000000003",
  "/geraete",
  "/wehren",
  "/verwaltung",
  "/admin",
];

// Geschützte API-Routen (401-Manifest). Neue API-Routen hier ergänzen.
const PROTECTED_API = ["/api/fahrzeuge", "/api/geraete", "/api/verwaltung"];

// Öffentliche Routen (Middleware-Allowlist).
const PUBLIC_ROUTES = ["/login", "/api/health"];

test.describe("Default-deny: geschützte Seiten", () => {
  for (const path of PROTECTED_PAGES) {
    test(`anonymer Aufruf von ${path} leitet auf /login um`, async ({
      page,
    }) => {
      await page.goto(path);
      await expect(page).toHaveURL(/\/login/);
    });
  }
});

test.describe("Default-deny: geschützte API-Routen", () => {
  for (const path of PROTECTED_API) {
    test(`anonymer Aufruf von ${path} liefert 401 ohne Daten-Leak`, async ({
      request,
    }) => {
      const res = await request.get(path);
      expect(res.status()).toBe(401);
      const body = await res.text();
      // Kein Daten-Leak: nur eine generische Fehlermeldung.
      expect(body).not.toContain("brigade");
      expect(body).not.toContain("passwort");
    });
  }
});

test.describe("Öffentliche Routen bleiben erreichbar", () => {
  test("Login-Seite ist anonym erreichbar", async ({ page }) => {
    await page.goto("/login");
    await expect(
      page.getByRole("heading", { name: "Anmelden" }),
    ).toBeVisible();
  });

  test("Health-Check ist anonym 200", async ({ request }) => {
    const res = await request.get("/api/health");
    expect(res.status()).toBe(200);
    expect(await res.json()).toEqual({ status: "ok" });
  });
});

void PUBLIC_ROUTES;
