import { execFileSync } from "node:child_process";
import { readFileSync } from "node:fs";
import { join } from "node:path";
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";

const requiredEnvironment = (name: string): string => {
  const value = process.env[name]?.trim();
  if (!value) throw new Error(`${name} is required for the destructive self-project smoke`);
  return value;
};

const suite = process.env.AWP_DESTRUCTIVE_SMOKE === "1" ? 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;
  let databaseUrl: string;
  let repositoryUrl: string;
  let visionFile: string;

  beforeAll(async () => {
    databaseUrl = requiredEnvironment("AWP_TEST_POSTGRES_URL");
    repositoryUrl = requiredEnvironment("AWP_SELF_REPOSITORY_URL");
    visionFile = join(requiredEnvironment("AWP_PROJECT_CHECKOUT_PATH"), "docs", "VISION.md");
    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,
      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 response = await fetch(`http://127.0.0.1:${running.port}/internal/projects/${projectId}`);
    expect(response.status).toBe(200);
    const hierarchy = (await response.json()) as { vision?: { summary: string } };
    expect(hierarchy.vision?.summary).toBe(readFileSync(visionFile!, "utf8").trim());
  });
});
