import type { CoverageManifest } from "./coverage";
import type { RateLimitBudget } from "../rate-limit/rate-limit.interface";

/**
 * Per-use-case manifest entry. Declares what the use case does at the contract
 * level: whether it mutates state, what audit events it emits, what cross-feature
 * events it publishes or consumes. The conformance system reads these to
 * derive binding-slot types and to verify code against manifest declarations.
 */
export type UseCaseManifest = {
  readonly mutates: boolean;
  readonly audits: readonly string[];
  readonly publishes: readonly string[];
  readonly consumes: readonly string[];
  readonly analyticsEvents?: readonly string[];
  readonly rateLimit?: readonly RateLimitBudget[];
};

/**
 * The feature-level manifest. One per feature package, conventionally exported
 * as `<featureName>Manifest` from `src/feature.manifest.ts`.
 *
 * `coverage` is optional for backward compatibility — features without a
 * declared coverage section fall back to `DEFAULT_COVERAGE_BANDS` via
 * `getCoverageBands(manifest)` (see `./coverage.ts`).
 */
export type FeatureManifest = {
  readonly name: string;
  readonly requiredCores: readonly string[];
  readonly useCases: { readonly [k: string]: UseCaseManifest };
  readonly realtimeChannels: readonly string[];
  readonly jobs: readonly string[];
  readonly coverage?: CoverageManifest;
  /**
   * Consent categories this feature's use cases require before processing
   * personal data. When non-empty, `assertFeatureConformance` requires every
   * bound use case to carry the `__consentChecked` brand from `withConsent`.
   * Defaults to `[]` — existing features with no consent requirements omit
   * or declare an empty array.
   */
  readonly requiresConsent?: readonly string[];
};

/**
 * Identity helper that exists purely to widen the input type to satisfy
 * `FeatureManifest` while preserving the literal types of the `as const`
 * input. Downstream types (`ProductionUseCase<I, O, M>`) consume the
 * preserved literals to derive binding-slot brand requirements.
 *
 * Usage:
 *
 *   export const authManifest = defineFeature({ name: "auth", ... } as const);
 */
export function defineFeature<const M extends FeatureManifest>(manifest: M): M {
  return manifest;
}
