import { Injectable } from '@nestjs/common';
import type { Scope } from 'shared-auth';

/**
 * Resolves the portal-side scopes for a user being signed in.
 *
 * Per [ADR-0025 §"Sources of truth — apf_portal-side `user_scopes`
 * table"](../../../../docs/decisions/0025-authorization-model-privileges-roles-scopes.md),
 * scopes are *not* carried by Entra: they live in the portal-side
 * `user_scopes` Prisma table (per ADR-0026 PR 1's schema), keyed on
 * `User.id` (UUID). Each row materialises one `Scope` entry on the
 * session-resident principal.
 *
 * The seam is here in v1 so ADR-0026 PR 2 (the `PrismaScopeResolver`
 * landing the seed + the `/admin/users/:id/scopes` screen) replaces
 * only the implementation, leaving the call-site in
 * `PrincipalBuilder` untouched. The v1 stub (`StubScopeResolver`)
 * always returns `[{ kind: 'unrestricted' }]` per ADR-0025 §331.
 *
 * Note: the `input` shape switched from `{ entraOid }` to `{ userId }`
 * with ADR-0026 PR 1 (Person + User + UserScope schema landed). The
 * stub ignores its argument either way; the change is the seam for
 * PR 2's Prisma resolver, which keys queries on `User.id`.
 */
export abstract class ScopeResolver {
  abstract resolve(input: { userId: string }): Promise<ReadonlyArray<Scope>>;
}

/**
 * v1 stub — returns `unrestricted` for every user. Per ADR-0025
 * §"Sources of truth — apf_portal-side `user_scopes` table" the
 * real implementation queries `user_scopes WHERE userId = ?`; that
 * lands as `PrismaScopeResolver` in ADR-0026 PR 2 alongside the
 * test-tenant seed.
 *
 * Deliberately not an in-memory hard-coded persona-keyed map: the
 * 19 test personas have *intended* scopes (see
 * `notes/test-tenant-role-assignments.md`) but those scopes have
 * no guard consuming them yet, so per-persona stub data would be
 * write-only documentation. ADR-0026 PR 2 populates the table; this
 * class is replaced by a Prisma-backed implementation in the same
 * change.
 */
@Injectable()
export class StubScopeResolver extends ScopeResolver {
  override resolve(): Promise<ReadonlyArray<Scope>> {
    return Promise.resolve([{ kind: 'unrestricted' }]);
  }
}
