import { execFileSync } from "node:child_process";
import { readFileSync } from "node:fs";
import { join } from "node:path";
import { describe, expect, it } from "vitest";
import { createOperatorSession, operatorHeaders, requireOperatorPassword } from "./auth.js";

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

const suite = process.env.AWP_GOLIVE_EXECUTION === "1" ? describe : describe.skip;

suite("AC-28 canonical AWP self Project", () => {
  it("proves the manifest Project is AWP Project number one with canonical Vision evidence", async () => {
    const databaseUrl = requiredEnvironment("AWP_TEST_POSTGRES_URL");
    const controlPlaneUrl = requiredEnvironment("AWP_CONTROL_PLANE_URL").replace(/\/$/u, "");
    const projectId = requiredEnvironment("AWP_PROJECT_ID");
    const repositoryUrl = requiredEnvironment("AWP_REPOSITORY_REMOTE_URL");
    const checkoutPath = requiredEnvironment("AWP_REPOSITORY_CHECKOUT_PATH");
    const visionFile = join(checkoutPath, "docs", "VISION.md");
    const operatorPassword = requireOperatorPassword();
    const result = execFileSync(
      "psql",
      [
        databaseUrl,
        "--no-psqlrc",
        "--tuples-only",
        "--no-align",
        "--set",
        "ON_ERROR_STOP=1",
        "--set",
        `project_id=${projectId}`,
        "--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
         where p.id = :'project_id'
         group by p.id, p.repository_url;`,
      ],
      { encoding: "utf8" },
    ).trim();

    expect(result).not.toBe("");
    const [persistedProjectId, persistedRepositoryUrl, visionCount, isFirst] = result.split("|");
    expect(persistedProjectId).toBe(projectId);
    expect(persistedRepositoryUrl).toBe(repositoryUrl);
    expect(Number(visionCount)).toBeGreaterThanOrEqual(1);
    expect(isFirst).toBe("true");

    const token = await createOperatorSession(controlPlaneUrl, operatorPassword);
    const response = await fetch(
      `${controlPlaneUrl}/internal/projects/${encodeURIComponent(projectId)}`,
      { headers: operatorHeaders(token) },
    );
    expect(response.status).toBe(200);
    const hierarchy = (await response.json()) as {
      project?: { id: string; repositoryUrl: string };
      vision?: { summary: string };
    };
    expect(hierarchy.project).toMatchObject({ id: projectId, repositoryUrl });
    expect(hierarchy.vision?.summary).toBe(readFileSync(visionFile, "utf8").trim());
  });
});
