import { createServer } from "node:http";
import { describe, expect, it } from "vitest";
import type { Attempt } from "@awp/domain";
import {
  capability,
  unsafeOpaqueId,
  type AgentRunId,
  type AttemptId,
  type Connection,
  type ConnectionId,
  type CorrelationId,
  type CredentialReferenceId,
  type OperationId,
  type PrincipalId,
  type ProviderId,
  type ProviderOperationContext,
  type WorkspaceId,
} from "@awp/contracts";
import {
  createAuthorizedForceAccountHeaders,
  createAuthorizedForceAccountHeadersForAttempt,
  describeSubrouterCredentialAuthority,
  rejectAwpMutableCredentialOperation,
  SubrouterAccountProvider,
  SubrouterAdapterError,
  SubrouterHttpClient,
  SUBROUTER_FORCE_ACCOUNT_HEADER,
  SUBROUTER_SOURCE_PROOF,
  type SubrouterNativeClient,
} from "../../../packages/providers/account-subrouter/src/index.js";

function context(): ProviderOperationContext {
  return {
    operationId: unsafeOpaqueId<OperationId>("op-account-list"),
    idempotencyKey: "idem-account-list",
    correlationId: unsafeOpaqueId<CorrelationId>("corr-account-list"),
    connectionId: unsafeOpaqueId<ConnectionId>("connection-subrouter"),
    credentialReferenceId: unsafeOpaqueId<CredentialReferenceId>("credential-subrouter-admin"),
    authority: {
      principal: {
        id: unsafeOpaqueId<PrincipalId>("principal-system"),
        kind: "system",
        capabilities: [capability("account.read")],
      },
      capabilities: [capability("account.read")],
    },
  };
}

function canonicalAttempt(accountId: string | undefined): Attempt {
  return {
    id: unsafeOpaqueId<AttemptId>("attempt-subrouter"),
    agentRunId: unsafeOpaqueId<AgentRunId>("agent-run-subrouter"),
    workspaceId: unsafeOpaqueId<WorkspaceId>("workspace-subrouter"),
    status: "created",
    providerId: unsafeOpaqueId<ProviderId>("provider:acp"),
    ...(accountId === undefined ? {} : { accountId }),
    model: "gpt-5.3-codex-spark",
    revision: 1,
  };
}

function subrouterConnection(): Connection {
  return {
    id: unsafeOpaqueId<ConnectionId>("connection-subrouter"),
    providerId: unsafeOpaqueId<ProviderId>("provider:subrouter"),
    credentialReferenceId: unsafeOpaqueId<CredentialReferenceId>("credential-subrouter-grant"),
    status: "connected",
    accountIdentity: "codex-1",
    capabilities: [capability("account.read")],
    resources: ["codex-1"],
  };
}

describe("SubrouterAccountProvider", () => {
  it("records exact upstream, reference-consumer and Platform reuse-gate provenance", () => {
    expect(SUBROUTER_SOURCE_PROOF).toMatchObject({
      sourceRevision: "1c5719c702e16d7f458a2b5e20be9084fa88d86b",
      referenceConsumer: {
        upstreamRelease: "v0.1.81",
        upstreamRevision: "29c7ebb306ac54739206f4752449e437047dd150",
        reuseDisposition: "reference-only-do-not-copy-overdeck-patch",
      },
      platformReuseGate: {
        revision: "801cad34010b87ed58e6450bed31c59d12b8f21a",
        providerAccountAuthorityCapability: false,
        disposition: "subrouter-behind-awp-account-provider-seam",
      },
    });
  });

  it("maps native accounts without exposing credentials", async () => {
    const client: SubrouterNativeClient = {
      async listAccounts() {
        return [
          {
            id: "codex-1",
            provider: "codex",
            auth_mode: "oauth",
            label: "Codex primary",
            email: "codex@example.test",
            source: "/var/lib/subrouter/codex-1.json",
          },
          {
            id: "apikey:backup",
            provider: "claude",
            auth_mode: "apikey",
            source: "manual",
          },
        ];
      },
    };
    const result = await new SubrouterAccountProvider(client).listAccounts(context());

    expect(result.value).toEqual([
      {
        accountKey: "codex-1",
        label: "Codex primary",
        capabilities: ["auth.oauth", "provider.codex"],
      },
      {
        accountKey: "apikey:backup",
        label: "apikey:backup",
        capabilities: ["auth.apikey", "provider.claude"],
      },
    ]);
    expect(JSON.stringify(result)).not.toContain("token");
  });

  it("forces only an explicitly authorized account and never derives authority from user metadata", () => {
    const headers = createAuthorizedForceAccountHeaders({
      forceAccountKey: "codex-2",
      authorizedAccountKeys: ["codex-1", "codex-2"],
    });

    expect(headers).toEqual({ [SUBROUTER_FORCE_ACCOUNT_HEADER]: "codex-2" });
    expect(Object.keys(headers)).toEqual([SUBROUTER_FORCE_ACCOUNT_HEADER]);
    expect(headers).not.toHaveProperty("X-Subrouter-User-Email");
  });

  it("projects the canonical C1 Attempt account provenance into an authorized force-account header", () => {
    const headers = createAuthorizedForceAccountHeadersForAttempt(canonicalAttempt("codex-2"), [
      "codex-1",
      "codex-2",
    ]);
    expect(headers).toEqual({ [SUBROUTER_FORCE_ACCOUNT_HEADER]: "codex-2" });
  });

  it("fails closed when canonical C1 Attempt lacks account provenance", () => {
    expect(() =>
      createAuthorizedForceAccountHeadersForAttempt(canonicalAttempt(undefined), ["codex-1"]),
    ).toThrow(SubrouterAdapterError);
  });

  it("RT-008-B declares Subrouter as the sole mutable credential writer", () => {
    const authority = describeSubrouterCredentialAuthority(subrouterConnection());
    expect(authority).toEqual({
      connectionId: unsafeOpaqueId<ConnectionId>("connection-subrouter"),
      credentialReferenceId: unsafeOpaqueId<CredentialReferenceId>("credential-subrouter-grant"),
      mutableOwner: "subrouter",
      awpMutableWriter: false,
    });
  });

  it("RT-008-B rejects AWP-side refresh/rotation of a Subrouter-owned grant", () => {
    for (const operation of ["refresh", "rotate", "revocation-reconcile"] as const) {
      expect(() => rejectAwpMutableCredentialOperation(operation)).toThrow(SubrouterAdapterError);
      try {
        rejectAwpMutableCredentialOperation(operation);
      } catch (error) {
        expect((error as SubrouterAdapterError).providerError).toMatchObject({
          category: "permission",
          retryable: false,
        });
      }
    }
  });

  it("rejects an unauthorized explicit account pin", () => {
    expect(() =>
      createAuthorizedForceAccountHeaders({
        forceAccountKey: "privileged",
        authorizedAccountKeys: ["ordinary"],
      }),
    ).toThrow(SubrouterAdapterError);

    try {
      createAuthorizedForceAccountHeaders({
        forceAccountKey: "privileged",
        authorizedAccountKeys: ["ordinary"],
      });
    } catch (error) {
      expect((error as SubrouterAdapterError).providerError.category).toBe("permission");
    }
  });

  it("normalizes provider capacity failures", async () => {
    const client: SubrouterNativeClient = {
      async listAccounts() {
        throw { status: 429 };
      },
    };

    await expect(
      new SubrouterAccountProvider(client).listAccounts(context()),
    ).rejects.toMatchObject({
      providerError: { category: "rate-capacity", retryable: true },
    });
  });
});

describe("SubrouterHttpClient", () => {
  it("reads the real Subrouter account-list HTTP seam without exposing its admin token", async () => {
    const seenAuthorization: string[] = [];
    const server = createServer((request, response) => {
      seenAuthorization.push(request.headers.authorization ?? "");
      if (request.url !== "/_subrouter/accounts") {
        response.writeHead(404).end();
        return;
      }
      response.writeHead(200, { "content-type": "application/json" });
      response.end(
        JSON.stringify([
          {
            id: "codex-k3s",
            provider: "codex",
            auth_mode: "oauth",
            label: "K3s Codex",
            email: "k3s@example.test",
            source: "/var/lib/subrouter/codex-k3s.json",
          },
        ]),
      );
    });
    await new Promise<void>((resolve) => server.listen(0, "127.0.0.1", resolve));
    try {
      const address = server.address();
      if (typeof address !== "object" || address === null)
        throw new Error("test server did not bind");
      const secret = "k3s-admin-secret-not-a-provider-credential";
      const client = new SubrouterHttpClient({
        baseUrl: `http://127.0.0.1:${address.port}`,
        adminToken: secret,
      });
      const accounts = await client.listAccounts();
      expect(accounts).toEqual([
        {
          id: "codex-k3s",
          provider: "codex",
          auth_mode: "oauth",
          label: "K3s Codex",
          email: "k3s@example.test",
          source: "/var/lib/subrouter/codex-k3s.json",
        },
      ]);
      expect(seenAuthorization).toEqual([`Bearer ${secret}`]);
      expect(JSON.stringify(accounts)).not.toContain(secret);
    } finally {
      await new Promise<void>((resolve, reject) =>
        server.close((error) => (error ? reject(error) : resolve())),
      );
    }
  });

  it("accepts a credential-empty Subrouter account pool", async () => {
    const server = createServer((_request, response) => {
      response.writeHead(200, { "content-type": "application/json" });
      response.end("[]");
    });
    await new Promise<void>((resolve) => server.listen(0, "127.0.0.1", resolve));
    try {
      const address = server.address();
      if (typeof address !== "object" || address === null)
        throw new Error("test server did not bind");
      const accounts = await new SubrouterHttpClient({
        baseUrl: `http://127.0.0.1:${address.port}`,
        adminToken: "empty-pool-admin",
      }).listAccounts();
      expect(accounts).toEqual([]);
    } finally {
      await new Promise<void>((resolve, reject) =>
        server.close((error) => (error ? reject(error) : resolve())),
      );
    }
  });
});
