import { expect, test } from "bun:test";
import { spawnSync } from "node:child_process";
import { resolve } from "node:path";
import { assertNoDuplicateYamlMappingKeys } from "./platform-infra-ops-library";

const repositoryRoot = resolve(import.meta.dir, "../..");

test("Gitea plan renders a single-writer durable inbox PVC from owning YAML", () => {
  const result = cli(["platform-infra", "gitea", "plan", "--target", "NC01", "--raw"]);
  expect(result.status).toBe(0);
  const data = result.payload.data;
  expect(data.ok).toBe(true);
  expect(data.renderPlan.objects).toContainEqual({
    kind: "PersistentVolumeClaim",
    name: "gitea-github-sync-inbox",
    namespace: "devops-infra",
  });
  expect(data.policy).toContainEqual(expect.objectContaining({ name: "durable-inbox-single-writer", ok: true }));
  expect(data.policy).toContainEqual(expect.objectContaining({ name: "durable-inbox-pvc", ok: true }));
});

test("manual mirror sync and synthetic webhook delivery fail before remote capture", () => {
  const sync = cli(["platform-infra", "gitea", "mirror", "sync", "--target", "NC01", "--confirm", "--raw"]);
  expect(sync.status).not.toBe(0);
  expect(sync.payload.data).toMatchObject({
    ok: false,
    mutation: false,
    mode: "automatic-source-authority-manual-sync-disabled",
  });
  expect(sync.payload.data.remote).toBeUndefined();

  const webhookTest = cli(["platform-infra", "gitea", "mirror", "webhook", "test", "--target", "NC01", "--repo", "unidesk-master-nc01", "--confirm", "--raw"]);
  expect(webhookTest.status).not.toBe(0);
  expect(webhookTest.payload.data).toMatchObject({
    ok: false,
    error: "unsupported-platform-infra-gitea-mirror-webhook-command",
  });
  expect(webhookTest.payload.data.remote).toBeUndefined();
});

test("YAML parser rejects duplicate mapping keys before silent overwrite", () => {
  expect(() => assertNoDuplicateYamlMappingKeys(`sourceAuthority:
  repositories:
    - key: agentrun-jd01-v02
      legacyGitMirror:
        configRef: first
        configRef: second
`, "duplicate.yaml")).toThrow(/duplicate YAML mapping key configRef.*first declared at line 5/);
});

test("default platform-infra help exposes only read-only Gitea authority commands", () => {
  const result = cli(["platform-infra", "gitea", "--help"]);
  expect(result.status).toBe(0);
  const giteaUsage = (result.payload.data.usage as string[]).filter((line) => line.includes("platform-infra gitea "));
  expect(giteaUsage).toEqual([
    "bun scripts/cli.ts platform-infra gitea status --target <NODE> [--full|--raw]",
    "bun scripts/cli.ts platform-infra gitea validate --target <NODE> [--full|--raw]",
    "bun scripts/cli.ts platform-infra gitea mirror status --target <NODE> [--full|--raw]",
    "bun scripts/cli.ts platform-infra gitea mirror webhook status --target <NODE> [--repo <key>] [--delivery-id <id>] [--full|--raw]",
  ]);
  expect(giteaUsage.join("\n")).not.toMatch(/\b(?:apply|sync|flush|trigger)\b/);
});

function cli(args: string[]): { status: number | null; payload: Record<string, any> } {
  const result = spawnSync("bun", ["scripts/cli.ts", ...args], {
    cwd: repositoryRoot,
    encoding: "utf8",
    env: { ...process.env, NO_COLOR: "1" },
  });
  expect(result.stdout).not.toBe("");
  return { status: result.status, payload: JSON.parse(result.stdout) };
}
