import { execFileSync } from "node:child_process";
import { readFileSync } from "node:fs";
import { fileURLToPath } from "node:url";
import { sql } from "drizzle-orm";
import { createPostgresJsClient } from "@platform-modules/db/postgres/postgres-js";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import {
  startControlPlane,
  type RunningControlPlane,
} from "../../apps/control-plane/src/server.js";
import { schema } from "@awp/persistence";
import {
  TEST_OPERATOR_PASSWORD,
  TEST_OPERATOR_PASSWORD_HASH,
  createOperatorSession,
  operatorHeaders,
} from "../golive/auth.js";

const databaseUrl = process.env.AWP_TEST_POSTGRES_URL;
const repositoryUrl = process.env.AWP_SELF_REPOSITORY_URL;
const visionFile = process.env.AWP_VISION_FILE;
const enabled = databaseUrl && repositoryUrl && visionFile;
const suite = enabled ? describe : describe.skip;
const migrationsFolder = fileURLToPath(
  new URL("../../packages/persistence/drizzle/", import.meta.url),
);

suite("self Project bootstrap persistence smoke (non-GOLIVE)", () => {
  let running: RunningControlPlane;

  beforeAll(async () => {
    const admin = createPostgresJsClient({ connectionString: databaseUrl!, schema });
    await admin.execute(sql.raw("drop schema if exists drizzle cascade"));
    await admin.execute(sql.raw("drop schema public cascade"));
    await admin.execute(sql.raw("create schema public"));
    await admin.$client.end({ timeout: 5 });
    running = await startControlPlane({
      databaseUrl: databaseUrl!,
      migrationsFolder,
      port: 0,
      operatorPasswordHash: TEST_OPERATOR_PASSWORD_HASH,
      selfProject: { repositoryUrl: repositoryUrl!, visionFile: visionFile! },
    });
  }, 30_000);

  afterAll(async () => {
    await running?.close();
  });

  it("registers AWP first with a ProjectVision derived from docs/VISION.md", async () => {
    const result = execFileSync(
      "psql",
      [
        databaseUrl!,
        "--no-psqlrc",
        "--tuples-only",
        "--no-align",
        "--set",
        "ON_ERROR_STOP=1",
        "--command",
        `select p.id || '|' || p.repository_url || '|' || count(v.id) || '|' ||
          (p.id = (select first_project.id from projects first_project
            order by first_project.created_at, first_project.id limit 1))
         from projects p
         join project_vision_versions v on v.project_id = p.id
         group by p.id, p.repository_url;`,
      ],
      { encoding: "utf8" },
    ).trim();
    const [projectId, persistedRepositoryUrl, visionCount, isFirst] = result.split("|");
    expect(projectId).toBeTruthy();
    expect(persistedRepositoryUrl).toBe(repositoryUrl);
    expect(Number(visionCount)).toBeGreaterThanOrEqual(1);
    expect(isFirst).toBe("true");

    const baseUrl = `http://127.0.0.1:${running.port}`;
    const token = await createOperatorSession(baseUrl, TEST_OPERATOR_PASSWORD);
    const response = await fetch(`${baseUrl}/internal/projects/${projectId}`, {
      headers: operatorHeaders(token),
    });
    expect(response.status).toBe(200);
    const hierarchy = (await response.json()) as { vision?: { summary: string } };
    expect(hierarchy.vision?.summary).toBe(readFileSync(visionFile!, "utf8").trim());
  });
});
