'use strict';
const test = require('node:test');
const assert = require('node:assert');
const { isOverParseCap, parseCapState, maxParseBytes, DEFAULT_MAX_PARSE_BYTES } = require('./size-cap');

test('size-cap', async (t) => {
  // Never mutate process.env at module top level — set/restore around the test.
  const ORIG = process.env.CTM_MAX_PARSE_BYTES;
  t.after(() => {
    if (ORIG === undefined) delete process.env.CTM_MAX_PARSE_BYTES;
    else process.env.CTM_MAX_PARSE_BYTES = ORIG;
  });

  await t.test('default cap is 256 MiB', () => {
    delete process.env.CTM_MAX_PARSE_BYTES;
    assert.equal(maxParseBytes(), 256 * 1024 * 1024);
    assert.equal(DEFAULT_MAX_PARSE_BYTES, 256 * 1024 * 1024);
  });

  await t.test('over/under boundary', () => {
    delete process.env.CTM_MAX_PARSE_BYTES;
    const cap = 256 * 1024 * 1024;
    assert.equal(isOverParseCap(cap), false, 'exactly at cap is not over');
    assert.equal(isOverParseCap(cap + 1), true, 'one over cap is over');
    assert.equal(isOverParseCap(cap - 1), false);
    assert.equal(isOverParseCap(7.4 * 1024 * 1024 * 1024), true, '7.4GB is over');
  });

  await t.test('fails OPEN on unmeasurable sizes', () => {
    delete process.env.CTM_MAX_PARSE_BYTES;
    for (const bad of [undefined, null, NaN, 0, -1, -1e9, 'abc', Infinity, -Infinity]) {
      assert.equal(isOverParseCap(bad), false, `${String(bad)} must not be over cap (fail open)`);
    }
  });

  await t.test('env override applies', () => {
    process.env.CTM_MAX_PARSE_BYTES = String(1000);
    assert.equal(maxParseBytes(), 1000);
    assert.equal(isOverParseCap(1001), true);
    assert.equal(isOverParseCap(1000), false);
    assert.equal(isOverParseCap(999), false);
  });

  await t.test('invalid env override falls back to default', () => {
    process.env.CTM_MAX_PARSE_BYTES = 'not-a-number';
    assert.equal(maxParseBytes(), DEFAULT_MAX_PARSE_BYTES);
    process.env.CTM_MAX_PARSE_BYTES = '-5';
    assert.equal(maxParseBytes(), DEFAULT_MAX_PARSE_BYTES);
    process.env.CTM_MAX_PARSE_BYTES = '0';
    assert.equal(maxParseBytes(), DEFAULT_MAX_PARSE_BYTES);
  });

  await t.test('parseCapState shape', () => {
    delete process.env.CTM_MAX_PARSE_BYTES;
    const s = parseCapState(300 * 1024 * 1024);
    assert.equal(s.overCap, true);
    assert.equal(s.bytes, 300 * 1024 * 1024);
    assert.equal(s.cap, 256 * 1024 * 1024);
    const u = parseCapState(undefined);
    assert.deepEqual({ overCap: u.overCap, bytes: u.bytes }, { overCap: false, bytes: 0 });
  });
});
