import { Inject, Injectable } from '@nestjs/common';
import type { JWK } from 'jose';
import { BFF_SIGNING_KEY, type BffSigningKey } from './bff-signing-key';

/**
 * Builds the JWKS payload served at `/.well-known/jwks.json` per
 * [ADR-0014](../../../../docs/decisions/0014-downstream-api-access-obo-pattern.md)
 * §"Service strategy". v1 returns a single public key; the rotation
 * chantier extends `keys` to a window of currently-valid material
 * so a downstream that cached a previous JWK keeps verifying during
 * cut-over.
 *
 * **Why a service, not a `@Controller`.** Path-to-regexp v8 (used
 * by Nest 11) parses controller paths through a grammar that does
 * not cleanly route a leading-dot segment like `.well-known/...`
 * to a bare-root URL — the original `@Controller('.well-known/jwks.json')`
 * + `setGlobalPrefix('api', { exclude: ... })` combination landed
 * the route at neither `/api/.well-known/jwks.json` nor
 * `/.well-known/jwks.json`. We sidestep the whole class of bug by
 * registering the JWKS handler at the Express layer in `main.ts`
 * (before Nest's router) and letting this service produce the
 * payload. The Nest DI graph still owns the BFF signing key — only
 * the route wiring lives outside.
 *
 * **No auth / no CSRF.** Public by design — the JWKS is the
 * downstream's verification anchor; gating it would defeat the
 * purpose. The CSRF middleware exempts GET, and the route is
 * mounted ahead of the rate limiter so a hammered JWKS endpoint
 * can't lock the rest of the BFF out — discovery endpoints are
 * meant to be polled.
 */
@Injectable()
export class JwksPublisher {
  constructor(@Inject(BFF_SIGNING_KEY) private readonly key: BffSigningKey) {}

  jwks(): { keys: readonly JWK[] } {
    return { keys: [this.key.publicJwk] };
  }
}
