import { describe, expect, test } from "bun:test";
import { buildMirrorWebhookStatusDisclosure, rawMirrorWebhookStatus } from "./platform-infra-gitea-disclosure";
import { renderMirrorWebhookStatus } from "./platform-infra-gitea-render";

describe("Gitea webhook status progressive disclosure", () => {
  test("keeps --full as a bounded domain aggregate with repository drill-down commands", () => {
    const view = buildMirrorWebhookStatusDisclosure(fixture(), { repoKey: null, deliveryId: null });
    const serialized = JSON.stringify({ ok: true, command: "status --full", data: view }, null, 2);

    expect(view.ok).toBe(true);
    expect(view.view).toBe("domain-aggregate");
    expect((view.repositories as unknown[]).length).toBe(2);
    expect((view.deliveries as unknown[]).length).toBe(2);
    expect((view.bridge as { durableInbox: { retainedDeliveryCount: number } }).durableInbox.retainedDeliveryCount).toBe(82);
    expect(Object.prototype.hasOwnProperty.call(view, "raw")).toBe(false);
    expect(serialized).not.toContain('"payloadSha"');
    expect(serialized).not.toContain("outputTruncated");
    expect(Buffer.byteLength(serialized, "utf8")).toBeLessThan(10_240);
    expect((view.next as { repositories: Array<{ command: string }> }).repositories[0]?.command).toContain("--repo repo-a");
  });

  test("repository and deliveryId drill-down expose one inbox record, retry, logs and first error", () => {
    const repository = buildMirrorWebhookStatusDisclosure(fixture(), { repoKey: "repo-a", deliveryId: null });
    expect(repository.view).toBe("repository-drill-down");
    expect((repository.deliveries as unknown[]).length).toBe(1);
    expect((repository.selection as { effectiveDeliveryId: string }).effectiveDeliveryId).toBe("delivery-current-a");
    expect((repository.retry as { totalAttempts: number }).totalAttempts).toBe(1);
    const recovery = (repository.bridge as { durableInbox: { failedDeliveryRecovery: { entries: Array<Record<string, unknown>> } } }).durableInbox.failedDeliveryRecovery;
    expect(recovery.entries).toHaveLength(1);
    expect(recovery.entries[0]).toMatchObject({ deliveryId: "delivery-current-a", state: "attempted", attempts: 1, cooldownMs: 300_000, nextAt: "2026-07-11T00:05:00Z" });
    expect(JSON.stringify(recovery)).not.toContain("https://");

    const delivery = buildMirrorWebhookStatusDisclosure(fixture(), { repoKey: null, deliveryId: "delivery-5" });
    expect(delivery.ok).toBe(true);
    expect(delivery.view).toBe("delivery-drill-down");
    expect((delivery.selection as { selectedRepoKey: string }).selectedRepoKey).toBe("repo-a");
    expect((delivery.deliveries as Array<{ deliveryId: string }>)[0]?.deliveryId).toBe("delivery-5");
    expect((delivery.retry as { totalAttempts: number; lastError: string }).totalAttempts).toBe(3);
    expect((delivery.retry as { lastError: string }).lastError).toContain("authentication-failed");
    expect((delivery.logs as { matched: number; events: unknown[] }).matched).toBe(1);
    expect((delivery.diagnostics as { firstError: { domain: string } }).firstError.domain).toBe("durable-inbox-record");
  });

  test("reports missing retained delivery without hiding the operational payload", () => {
    const view = buildMirrorWebhookStatusDisclosure(fixture(), { repoKey: "repo-a", deliveryId: "not-retained" });
    expect(view.ok).toBe(false);
    expect((view.selection as { error: string }).error).toBe("delivery-not-observed-in-retained-evidence");

    const raw = rawMirrorWebhookStatus(fixture());
    expect(raw.view).toBe("raw");
    expect(raw.raw).toBeDefined();
    expect((raw.safety as { explicitRawRequired: boolean; valuesPrinted: boolean }).explicitRawRequired).toBe(true);
    expect((raw.safety as { valuesPrinted: boolean }).valuesPrinted).toBe(false);
  });

  test("keeps selected delivery GUID, status and accepted in one observation", () => {
    const input = fixture();
    const repo = (input.repositories as Array<Record<string, unknown>>)[0]!;
    repo.latestPushDelivery = { deliveryId: "newer-unrelated", statusCode: 202, status: "OK" };
    repo.selectedPushDelivery = { deliveryId: "selected-failed", hookId: 22, statusCode: 502, status: "misconfigured", deliveredAt: "2026-07-12T05:54:18Z" };
    repo.deliveryId = "selected-failed";
    repo.deliveryAccepted = false;

    const disclosure = buildMirrorWebhookStatusDisclosure(input, { repoKey: null, deliveryId: null });
    const summary = (disclosure.repositories as Array<{ selectedDelivery: Record<string, unknown> }>)[0]!.selectedDelivery;
    expect(summary).toMatchObject({ deliveryId: "selected-failed", hookId: 22, statusCode: 502, status: "misconfigured", accepted: false });

    const rendered = renderMirrorWebhookStatus(input, disclosure).renderedText;
    expect(rendered).toContain("selected-failed:502:misconfigured");
    expect(rendered).not.toContain("selected-failed:202:OK");
  });
});

function fixture(): Record<string, unknown> {
  const retained = Array.from({ length: 80 }, (_, index) => deliveryRecord(`delivery-${index}`, index === 5 || index % 2 === 0 ? "repo-a" : "repo-b", {
    totalAttempts: index === 5 ? 3 : 1,
    lastError: index === 5 ? { type: "authentication-failed", message: "authentication-failed" } : null,
  }));
  const currentA = deliveryRecord("delivery-current-a", "repo-a");
  const currentB = deliveryRecord("delivery-current-b", "repo-b");
  const bridge = {
    deployment: "gitea-github-sync",
    ready: true,
    readyReplicas: "1/1",
    serviceExists: true,
    durableInbox: {
      ready: true,
      storageReady: true,
      capacityAvailable: true,
      counts: { committed: 81, retryWait: 1 },
      deliveries: [...retained, currentA, currentB],
      totalBytes: 2048,
      maxBytes: 1_048_576,
      errorType: null,
      journal: { version: 1, kind: "GiteaGithubSyncDurableInbox", createdAt: "2026-07-11T00:00:00Z" },
      failedDeliveryRecovery: {
        enabled: true,
        ready: true,
        state: "ready",
        counts: { pending: 0, attempted: 2, "delivery-succeeded-awaiting-source": 0, "source-committed": 0, "terminal-exhausted": 0 },
        entries: [
          { repository: "pikasTech/repo-a", hookId: 1, deliveryId: "delivery-current-a", state: "attempted", attempts: 1, cooldownMs: 300_000, nextAt: "2026-07-11T00:05:00Z", updatedAt: "2026-07-11T00:00:00Z", lastStatusCode: 502 },
          { repository: "pikasTech/repo-b", hookId: 2, deliveryId: "delivery-current-b", state: "attempted", attempts: 2, cooldownMs: 300_000, nextAt: "2026-07-11T00:05:00Z", updatedAt: "2026-07-11T00:00:00Z", lastStatusCode: 504 },
        ],
      },
    },
  };
  return {
    ok: true,
    action: "platform-infra-gitea-mirror-webhook-status",
    mutation: false,
    target: { id: "NC01", route: "NC01:k3s", namespace: "devops-infra" },
    webhook: {
      enabled: true,
      direction: "github-to-gitea",
      publicUrl: "https://gitea.example/_unidesk/github-to-gitea/nc01",
      events: ["push"],
      responseBudgetMs: 8_000,
      ingressAttemptBudgetMs: 2_000,
      ingressResponseHeaderTimeoutMs: 3_000,
      ingressRetry: { enabled: true, maxAttempts: 3, initialDelayMs: 1_000, maxDelayMs: 30_000 },
      hookReconcile: { enabled: true, ownerTargetId: "NC01", runningOnTarget: true, intervalMs: 60_000, requestTimeoutMs: 15_000, desiredUrlSha256: "sha256:desired", topologySha256: "sha256:topology" },
      bridge: { deploymentName: "gitea-github-sync", serviceName: "gitea-github-sync", retry: { maxAttempts: 3, initialDelayMs: 1_000, maxDelayMs: 30_000 } },
    },
    bridge,
    repositories: [repository("repo-a", currentA), repository("repo-b", currentB)],
    bridgeLogs: {
      exitCode: 0,
      events: [
        { event: "github-to-gitea-sync", repo: "repo-a", deliveryId: "delivery-current-a", ok: true, terminal: true, syncAttempt: 1, disposition: "committed", elapsedMs: 90 },
        { event: "github-to-gitea-sync", repo: "repo-a", deliveryId: "delivery-5", ok: false, terminal: true, syncAttempt: 3, errorType: "authentication-failed", error: "authentication-failed", elapsedMs: 120 },
      ],
      errorTail: "",
    },
    mirrorStatus: { exitCode: 0, errorTail: "" },
    remote: { ok: true, bridge, repositories: [repository("repo-a", currentA), repository("repo-b", currentB)] },
  };
}

function repository(key: string, delivery: Record<string, unknown>): Record<string, unknown> {
  return {
    key,
    repository: `pikasTech/${key}`,
    branch: "master",
    hookReady: true,
    githubHead: "a".repeat(40),
    branchCommit: "a".repeat(40),
    snapshotCommit: "a".repeat(40),
    authorityMatches: true,
    bridgeEventStale: false,
    staleReason: null,
    deliveryId: delivery.deliveryId,
    deliveryAccepted: true,
    selectedPushDelivery: { deliveryId: delivery.deliveryId, hookId: 1, statusCode: 202, status: "OK", deliveredAt: "2026-07-11T00:00:00Z" },
    latestPushDelivery: { deliveryId: delivery.deliveryId, hookId: 1, statusCode: 202, status: "OK", deliveredAt: "2026-07-11T00:00:00Z" },
    hookTopology: {
      ready: true,
      desiredUrlSha256: "sha256:desired",
      desiredTopologyUrlSha256: ["sha256:desired"],
      observedManagedUrlSha256: ["sha256:desired"],
      driftTypes: [],
    },
    durableInboxState: "committed",
    durableInboxCommitted: true,
    durableInboxRecord: delivery,
    error: null,
  };
}

function deliveryRecord(deliveryId: string, repo: string, overrides: Record<string, unknown> = {}): Record<string, unknown> {
  return {
    deliveryId,
    repo,
    repository: `pikasTech/${repo}`,
    ref: "refs/heads/master",
    requestedCommit: "a".repeat(40),
    payloadSha: "b".repeat(64),
    state: "committed",
    acceptedSequence: 1,
    totalAttempts: 1,
    cycleAttempt: 1,
    nextAttemptAt: null,
    updatedAt: "2026-07-11T00:00:00Z",
    result: {
      sourceCommit: "a".repeat(40),
      authorityCommit: "a".repeat(40),
      snapshotRef: `refs/unidesk/snapshots/${repo}/${"a".repeat(40)}`,
      disposition: "atomic-source-authority-committed",
    },
    lastError: null,
    ...overrides,
  };
}
