import { SetMetadata, UseGuards, applyDecorators } from '@nestjs/common';
import type { FunctionalRole } from 'shared-auth';
import { RequireRoleGuard } from './require-role.guard';

/**
 * Reflector metadata key carrying the functional-role list a
 * route requires.
 */
export const REQUIRE_ROLE_METADATA = 'auth:require-role';

/**
 * `@RequireRole('rh', ...)` — gates a route on `principal.roles`
 * containing at least one of the listed `apf-role-*` slugs per
 * [ADR-0025 §"Guard surface"](../../../../docs/decisions/0025-authorization-model-privileges-roles-scopes.md).
 *
 * Multiple slugs compose as **OR** within the decorator. Stacking
 * `@RequireRole` with another guard (`@RequirePrivilege`,
 * `@RequireScope`, `@RequireMfa`) **AND**-combines at the Nest
 * level.
 *
 * The empty-list call is rejected at the type level by the
 * `[FunctionalRole, ...FunctionalRole[]]` tuple — a route can
 * not opt out of authorization by passing zero values.
 */
export function RequireRole(
  ...roles: [FunctionalRole, ...FunctionalRole[]]
): ClassDecorator & MethodDecorator {
  return applyDecorators(SetMetadata(REQUIRE_ROLE_METADATA, roles), UseGuards(RequireRoleGuard));
}
