/**
 * P0-12 smoke test — parseJsonBounded enforces a body size ceiling.
 *
 * Run: npx tsx scripts/smoke/p0-12-body-limit.ts
 */
import { ok, fail } from './_lib';
import {
    parseJsonBounded,
    BodyTooLargeError,
    BodyParseError,
} from '../../src/lib/api-helpers/parse-json';

async function main(): Promise<void> {
    // 1. Small body parses OK.
    const small = new Request('http://localhost/x', {
        method: 'POST',
        body: JSON.stringify({ k: 'v' }),
        headers: { 'content-type': 'application/json' },
    });
    const parsed = await parseJsonBounded<{ k: string }>(small);
    if (parsed.k !== 'v') fail('small body', `expected k=v got ${JSON.stringify(parsed)}`);
    ok('Small JSON body parsed');

    // 2. Oversize body via content-length → BodyTooLargeError.
    const liedAboutSize = new Request('http://localhost/x', {
        method: 'POST',
        body: 'x'.repeat(20),
        headers: { 'content-length': '9999999' },
    });
    try {
        await parseJsonBounded(liedAboutSize, { maxBytes: 100 });
        fail('content-length cap', 'expected BodyTooLargeError');
    } catch (err) {
        if (err instanceof BodyTooLargeError) ok('content-length cap rejects', err.message);
        else fail('content-length cap', `wrong error: ${String(err)}`);
    }

    // 3. Streamed overflow caught.
    const big = new Request('http://localhost/x', {
        method: 'POST',
        body: 'x'.repeat(5_000),
        headers: { 'content-type': 'application/json' },
    });
    try {
        await parseJsonBounded(big, { maxBytes: 1_000 });
        fail('stream cap', 'expected BodyTooLargeError');
    } catch (err) {
        if (err instanceof BodyTooLargeError) ok('streamed cap rejects', err.message);
        else fail('stream cap', `wrong error: ${String(err)}`);
    }

    // 4. Bad JSON → BodyParseError.
    const bad = new Request('http://localhost/x', {
        method: 'POST',
        body: '{nope}',
        headers: { 'content-type': 'application/json' },
    });
    try {
        await parseJsonBounded(bad);
        fail('bad json', 'expected BodyParseError');
    } catch (err) {
        if (err instanceof BodyParseError) ok('bad JSON rejected');
        else fail('bad json', `wrong error: ${String(err)}`);
    }

    ok('P0-12 body-limit', 'parseJsonBounded caps size and surfaces parse errors');
}

main().catch((err) => fail('P0-12 body-limit', String(err)));
