import type { IRateLimit } from "./rate-limit.interface";
import type { RateLimited } from "../conformance/brands";
import { attachBrand } from "../conformance/brand-runtime";

/**
 * Use-case wrapper applied at DI bind time. Attaches the `__rateLimited`
 * brand so the boot-time assertion can verify rate-limited use cases were
 * bound through the rate-limit-aware path.
 *
 * The forward closure keeps the brand on a fresh function so the original
 * `fn` reference is not mutated — important when the same factory output is
 * used elsewhere unwrapped (dev-seed paths, tests).
 *
 * Composition order (outermost to innermost):
 *   withSpan → withCapture → withAudit → withAnalytics → withRateLimit → factory(deps)
 */
export function withRateLimit<Args extends unknown[], R>(
  rateLimit: IRateLimit,
  fn: (...args: Args) => Promise<R>,
): RateLimited<(...args: Args) => Promise<R>> {
  void rateLimit; // future: enforce rate limit at runtime per manifest budgets
  const wrapped: (...args: Args) => Promise<R> = (...args) => fn(...args);
  attachBrand(wrapped, "__rateLimited");
  return wrapped as RateLimited<(...args: Args) => Promise<R>>;
}
