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

/**
 * Statische Migrations-Tests (laufen ohne Datenbank).
 * Verifizieren, dass die EINZIGE initiale Migration die geforderten Strukturen
 * und die Idempotenz-Absicherungen (DO-Block, IF NOT EXISTS, partieller Index)
 * enthält.
 */

const drizzleDir = join(process.cwd(), "drizzle");

function migrationSql(): string {
  const files = readdirSync(drizzleDir).filter((f) => f.endsWith(".sql"));
  expect(files.length).toBe(1); // genau EINE initiale Migration (alleiniger Eigentümer)
  return readFileSync(join(drizzleDir, files[0]!), "utf8");
}

describe("Initiale Migration", () => {
  const sql = migrationSql();

  it("erzeugt merkmal_values und alle 14 Tabellen idempotent", () => {
    expect(sql).toContain('CREATE TABLE IF NOT EXISTS "merkmal_values"');
    const tableCount = (sql.match(/CREATE TABLE IF NOT EXISTS/g) ?? []).length;
    expect(tableCount).toBe(14);
  });

  it("definiert 7 Enums in idempotenten DO-Blöcken", () => {
    for (const t of [
      "asset_status",
      "auth_typ",
      "entity_typ",
      "geltungsbereich",
      "merkmal_status",
      "merkmal_typ",
      "role",
    ]) {
      expect(sql).toContain(`CREATE TYPE "public"."${t}"`);
    }
    const enumDoBlocks = (
      sql.match(/DO \$\$ BEGIN CREATE TYPE/g) ?? []
    ).length;
    expect(enumDoBlocks).toBe(7);
  });

  it("hat die vier merkmal_values-Indizes (IF NOT EXISTS)", () => {
    for (const idx of [
      "mv_merkmal_num_idx",
      "mv_merkmal_bool_idx",
      "mv_merkmal_text_idx",
      "mv_entity_idx",
    ]) {
      expect(sql).toContain(`CREATE INDEX IF NOT EXISTS "${idx}"`);
    }
  });

  it("enthält den partiellen Unique-Index merkmale_active_name_uq WHERE status='active'", () => {
    expect(sql).toMatch(
      /CREATE UNIQUE INDEX IF NOT EXISTS "merkmale_active_name_uq" ON "merkmale"[^;]*WHERE[^;]*=\s*'active'/,
    );
  });

  it("enthält brigades_latlng_idx und login_attempts_key_zeit_idx", () => {
    expect(sql).toContain('CREATE INDEX IF NOT EXISTS "brigades_latlng_idx"');
    expect(sql).toContain(
      'CREATE INDEX IF NOT EXISTS "login_attempts_key_zeit_idx"',
    );
  });

  it("sichert Fremdschlüssel idempotent über DO-Blöcke ab", () => {
    const fkDoBlocks = (
      sql.match(/DO \$\$ BEGIN ALTER TABLE/g) ?? []
    ).length;
    expect(fkDoBlocks).toBe(15);
  });
});
