import { describe, expect, it } from "vitest";
import {
  attemptProviderReference,
  assertAttemptProvenanceImmutable,
  createAttemptSelectionProvenance,
  ImmutableAttemptProvenanceError,
  type Attempt,
} from "@awp/domain";
import {
  unsafeOpaqueId,
  type AgentRunId,
  type AttemptId,
  type ProviderId,
  type WorkspaceId,
} from "@awp/contracts";

const previousId = unsafeOpaqueId<AttemptId>("attempt-previous");
const providerId = unsafeOpaqueId<ProviderId>("provider-acp");
function attempt(): Attempt {
  return {
    id: unsafeOpaqueId<AttemptId>("attempt-current"),
    agentRunId: unsafeOpaqueId<AgentRunId>("agent-run"),
    workspaceId: unsafeOpaqueId<WorkspaceId>("workspace"),
    status: "created",
    providerId,
    accountId: "account-2",
    model: "model-b",
    selection: createAttemptSelectionProvenance({
      kind: "fallback",
      reason: "account quota exhausted",
      previousAttemptId: previousId,
    }),
    providerReference: {
      providerId,
      resourceType: "agent-session",
      nativeId: "session-42",
      observedAt: "2026-08-21T00:00:00Z",
    },
    revision: 1,
  };
}

describe("Attempt immutable retry/fallback provenance", () => {
  it("rejects changing selection reason on an existing Attempt", () => {
    const current = attempt();
    expect(() =>
      assertAttemptProvenanceImmutable(current, {
        ...current,
        selection: { ...current.selection, reason: "different reason" },
      }),
    ).toThrow(ImmutableAttemptProvenanceError);
  });

  it("exposes cancellation/reconciliation identity only as canonical ProviderReference", () => {
    const reference = attemptProviderReference(attempt());
    expect(reference).toMatchObject({
      providerId,
      resourceType: "agent-session",
      nativeId: "session-42",
    });
  });
});
