/**
 * Federation type definitions for SentryAgent.ai AgentIdP.
 * Covers federation partner management and cross-IdP token verification.
 */

// ============================================================================
// Federation Partner Status
// ============================================================================

/**
 * Lifecycle status of a federation partner.
 * - 'active'    — partner is trusted; tokens accepted.
 * - 'suspended' — partner is temporarily disabled; tokens rejected.
 * - 'expired'   — partner's expires_at has passed; tokens rejected.
 */
export type FederationPartnerStatus = 'active' | 'suspended' | 'expired';

// ============================================================================
// Federation Partner (database row)
// ============================================================================

/**
 * Represents a row in the `federation_partners` table.
 * A federation partner is an external IdP whose tokens this IdP trusts.
 */
export interface IFederationPartner {
  /** UUID primary key. */
  id: string;
  /** Human-readable partner name. */
  name: string;
  /** Issuer URL — must match the `iss` claim in federated tokens. */
  issuer: string;
  /** URL of the partner's JWKS endpoint. */
  jwks_uri: string;
  /**
   * Allowlist of organization_id values accepted from this partner.
   * An empty array means all organizations are accepted.
   */
  allowed_organizations: string[];
  /** Current lifecycle status. */
  status: FederationPartnerStatus;
  /** Timestamp when this partner was registered. */
  created_at: Date;
  /** Timestamp of the last update. */
  updated_at: Date;
  /** Optional expiry timestamp. NULL means the partner never expires. */
  expires_at: Date | null;
}

// ============================================================================
// Request / Response shapes
// ============================================================================

/**
 * Request body for registering a new federation partner.
 * POST /api/v1/federation/trust
 */
export interface ICreatePartnerRequest {
  /** Human-readable partner name. */
  name: string;
  /** Issuer URL of the external IdP. */
  issuer: string;
  /** URL of the partner's JWKS endpoint (must be reachable at registration time). */
  jwks_uri: string;
  /**
   * Optional allowlist of organization_id values to accept from this partner.
   * Defaults to empty array (all organizations accepted).
   */
  allowed_organizations?: string[];
  /** Optional ISO 8601 date-time string after which the partner will be expired. */
  expires_at?: string;
}

/**
 * Request body for updating an existing federation partner.
 * PATCH /api/v1/federation/partners/:id
 * All fields are optional; only provided fields are updated.
 */
export interface IUpdatePartnerRequest {
  /** Updated human-readable partner name. */
  name?: string;
  /** Updated JWKS endpoint URL. Cache will be invalidated if this changes. */
  jwks_uri?: string;
  /** Updated organization allowlist. */
  allowed_organizations?: string[];
  /** Updated lifecycle status. */
  status?: FederationPartnerStatus;
  /**
   * Updated expiry timestamp.
   * Pass an ISO 8601 string to set a new expiry, or null to clear it.
   */
  expires_at?: string | null;
}

/**
 * Request body for verifying a federated token.
 * POST /api/v1/federation/verify
 */
export interface IFederationVerifyRequest {
  /** The JWT token string to verify. */
  token: string;
  /**
   * Optional issuer hint. If provided, the token's `iss` claim must match this value exactly.
   * Useful to prevent issuer confusion when multiple partners share JWKS.
   */
  expected_issuer?: string;
}

/**
 * Result returned by a successful federated token verification.
 */
export interface IFederationVerifyResult {
  /** Whether the token is valid (true when verification passed). */
  valid: boolean;
  /** The issuer (`iss` claim) of the verified token. */
  issuer: string;
  /** The subject (`sub` claim) of the verified token. */
  subject: string;
  /**
   * The `organization_id` claim from the token, if present.
   * Populated when the external IdP includes this standard SentryAgent claim.
   */
  organization_id?: string;
  /** All claims from the verified token payload. */
  claims: Record<string, unknown>;
}

/**
 * Decoded claims payload of a federated JWT token.
 * Matches the standard JWT claims plus optional SentryAgent extensions.
 * Used internally by FederationService during token verification.
 */
export interface IFederatedTokenClaims {
  /** Issuer — identifies the external IdP. */
  iss: string;
  /** Subject — identifies the agent in the external IdP. */
  sub: string;
  /** Audience — the intended recipient(s) of the token. */
  aud: string | string[];
  /** Issued-at time (Unix seconds). */
  iat: number;
  /** Expiry time (Unix seconds). */
  exp: number;
  /**
   * Optional organization_id claim.
   * When present, used to enforce the partner's allowed_organizations filter.
   */
  organization_id?: string;
  /** Additional claims from the token payload. */
  [key: string]: unknown;
}
