/**
 * AUDIT-2 #15 smoke — Tier-1 hygiene fixes from docs/audit-2-followups.md.
 *
 * Six small security/correctness fixes bundled into one PR:
 *
 *   #15.1 — pinned-fetch always pins (no SSRF-bypass on allowlist hit)
 *           §1 in the followups doc.
 *   #15.2 — sanitizeErrorForResponse helper + applied to public routes
 *           §5 in the followups doc.
 *   #15.3 — NOC cookie 10y -> 30d
 *           §7 in the followups doc.
 *   #15.4 — ignoreTlsErrors gated to ADMIN-only in monitor create/update
 *           §8 in the followups doc.
 *   #15.5 — TRUSTED_PROXY_CIDRS renamed to ASSUME_BEHIND_PROXY
 *           §4 in the followups doc.
 *   #15.6 — worker.ts: exit on uncaughtException, let Docker restart
 *           §15 in the followups doc.
 *
 * This smoke statically asserts each fix is in place.
 */
import './_lib';
import { ok, fail } from './_lib';
import { readFileSync } from 'fs';
import path from 'path';

const ROOT = path.resolve(__dirname, '../..');

function read(rel: string): string {
    try { return readFileSync(path.join(ROOT, rel), 'utf8'); }
    catch (err) { fail(`read ${rel}`, String(err)); }
}

function assertPresent(label: string, src: string, needle: string | RegExp): void {
    const re = typeof needle === 'string'
        ? new RegExp(needle.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'))
        : needle;
    if (!re.test(src)) fail(label, `missing required pattern: ${String(needle)}`);
    ok(label);
}

function assertNotPresent(label: string, src: string, needle: string | RegExp): void {
    const re = typeof needle === 'string'
        ? new RegExp(needle.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'))
        : needle;
    if (re.test(src)) fail(label, `pattern still present: ${String(needle)}`);
    ok(label);
}

function main(): void {
    // #15.1 — pinned-fetch always pins
    const pinned = read('src/lib/network-security/pinned-fetch.ts');
    assertNotPresent(
        'audit2-15.1: no more `if (!pinnedIp)` bypass branch in pinned-fetch',
        pinned,
        /if\s*\(\s*!pinnedIp\s*\)\s*\{[\s\S]{0,200}fetch\(/,
    );
    assertPresent(
        'audit2-15.1: allowedHosts now blocks (not bypasses) — BlockedHostError on miss',
        pinned,
        /!allowed\.includes[\s\S]{0,200}BlockedHostError/,
    );

    // #15.2 — sanitize-error helper exists
    const helper = read('src/lib/api-helpers/sanitize-error.ts');
    assertPresent('audit2-15.2: sanitizeErrorForResponse exported', helper, /export function sanitizeErrorForResponse/);

    // Applied to /api/status
    const status = read('src/app/api/status/route.ts');
    assertPresent('audit2-15.2: status route imports sanitizeErrorForResponse', status, /sanitizeErrorForResponse/);
    assertNotPresent(
        'audit2-15.2: status route no longer leaks error.message verbatim',
        status,
        /error:\s*\(error as Error\)\.message/,
    );

    // audit3-followup (2026-05-30): the #15.2 NOC error-sanitization and
    // #15.3 NOC 30-day-cookie checks were removed — the NOC subsystem was
    // deleted in the executive-dashboard consolidation. The error-sanitization
    // discipline they guarded now lives on the executive token routes.

    // #15.4 — TLS-ignore ADMIN-only
    const monitors = read('src/app/api/monitors/route.ts');
    assertPresent(
        'audit2-15.4: monitors POST gates ignoreTlsErrors to ADMIN',
        monitors,
        /ignoreTlsErrors[\s\S]{0,300}userRole !== ['"]ADMIN['"]/,
    );
    assertPresent(
        'audit2-15.4: monitors PUT also gates ignoreTlsErrors',
        monitors,
        /updateData\?\.ignoreTlsErrors[\s\S]{0,200}session\.user\?\.role !== ['"]ADMIN['"]/,
    );

    // #15.5 — env var rename
    const trustedIp = read('src/lib/network-security/trusted-ip.ts');
    assertPresent('audit2-15.5: shouldTrustProxyHeaders helper exists', trustedIp, /shouldTrustProxyHeaders/);
    assertPresent('audit2-15.5: reads ASSUME_BEHIND_PROXY', trustedIp, /ASSUME_BEHIND_PROXY/);
    assertPresent('audit2-15.5: keeps backward-compat with TRUSTED_PROXY_CIDRS', trustedIp, /TRUSTED_PROXY_CIDRS/);
    const envExample = read('.env.example');
    assertPresent('audit2-15.5: .env.example documents ASSUME_BEHIND_PROXY', envExample, /ASSUME_BEHIND_PROXY/);

    // #15.6 — worker exits on uncaughtException
    const worker = read('scripts/worker.ts');
    assertPresent(
        'audit2-15.6: worker exits on uncaughtException',
        worker,
        /uncaughtException[\s\S]{0,500}process\.exit\(1\)/,
    );
    // unhandledRejection still log-and-continue (no exit nearby)
    assertNotPresent(
        'audit2-15.6: unhandledRejection still log-and-continue (no exit in handler)',
        worker,
        /unhandledRejection[\s\S]{0,200}process\.exit/,
    );

    ok(
        'audit2-15-tier1-hygiene',
        'six Tier-1 security/correctness items shipped: SSRF allowlist pin, error sanitization, NOC 30d cookie, TLS-ignore ADMIN-only, env var rename, worker exit-on-uncaught',
    );
}

main();
