/**
 * PR-A.1 smoke — /api/notification-rules authz gate.
 *
 * Pure-policy test against NotificationRuleAuthorization. The API route
 * wires the policy + the existing requireAuthContext() so the policy is
 * the load-bearing piece. If the matrix below holds, the IDOR is closed.
 *
 * Run: npx tsx scripts/smoke/pra-1-notification-rules-authz.ts
 */
import './_lib';
import { ok, fail } from './_lib';
import { NotificationRuleAuthorization } from '../../src/lib/authorization/notification-rule.authz';
import { AuthorizationError } from '../../src/lib/authorization/types';

type Role = 'ADMIN' | 'ADMIN_READ_ONLY' | 'EDITOR' | 'VIEWER';
const ctx = (role: Role) => ({ userId: 1, role });

function expectThrows(fn: () => void, label: string) {
    try {
        fn();
    } catch (err) {
        if (err instanceof AuthorizationError) return;
        fail(label, `expected AuthorizationError, got ${err}`);
    }
    fail(label, 'expected throw, got success');
}

function expectNoThrow(fn: () => void, label: string) {
    try {
        fn();
    } catch (err) {
        fail(label, `unexpected throw: ${err}`);
    }
}

function main(): void {
    // Read gate: ADMIN + ADMIN_READ_ONLY only
    expectNoThrow(() => NotificationRuleAuthorization.assertCanRead(ctx('ADMIN')), 'ADMIN read');
    expectNoThrow(() => NotificationRuleAuthorization.assertCanRead(ctx('ADMIN_READ_ONLY')), 'ADMIN_READ_ONLY read');
    expectThrows(() => NotificationRuleAuthorization.assertCanRead(ctx('EDITOR')), 'EDITOR read denied');
    expectThrows(() => NotificationRuleAuthorization.assertCanRead(ctx('VIEWER')), 'VIEWER read denied');
    ok('read gate: ADMIN + ADMIN_READ_ONLY only');

    // Write gate: ADMIN only
    expectNoThrow(() => NotificationRuleAuthorization.assertCanWrite(ctx('ADMIN')), 'ADMIN write');
    expectThrows(() => NotificationRuleAuthorization.assertCanWrite(ctx('ADMIN_READ_ONLY')), 'ADMIN_READ_ONLY write denied');
    expectThrows(() => NotificationRuleAuthorization.assertCanWrite(ctx('EDITOR')), 'EDITOR write denied');
    expectThrows(() => NotificationRuleAuthorization.assertCanWrite(ctx('VIEWER')), 'VIEWER write denied');
    ok('write gate: ADMIN only');

    ok('PR-A.1 notification-rules authz smoke', 'IDOR closed at the policy layer');
}

main();
