import { describe, test, expect, beforeAll, afterAll } from 'bun:test';
import { setupFileRig, type FileTestRig } from '../integration/helpers/rig.js';
import { FsRateLimitError, QuotaExceededError, type FileEntry } from '../../src/index.js';

describe('Op rate limit', () => {
  let rig: FileTestRig;
  let listCount = 0;
  beforeAll(async () => {
    listCount = 0;
    rig = await setupFileRig({
      rateLimits: { maxOpsPerMinutePerSender: 5 },
      list: async () => {
        listCount++;
        return { entries: [], hasMore: false };
      },
    });
  });
  afterAll(async () => { await rig.teardown(); });

  test('op rate-limit kicks in after capacity', async () => {
    listCount = 0;
    for (let i = 0; i < 5; i++) await rig.fs.list('/');
    expect(listCount).toBe(5);
    await expect(rig.fs.list('/')).rejects.toBeInstanceOf(FsRateLimitError);
  });
});

describe('Byte quota', () => {
  let rig: FileTestRig;
  beforeAll(async () => {
    rig = await setupFileRig({
      rateLimits: {
        // Plenty of ops, but tight byte cap for the quota test.
        maxOpsPerMinutePerSender: 100,
        maxBytesPerHourPerSender: 1024,
      },
      write: async (ctx) => {
        const e: FileEntry = {
          name: ctx.args.path.split('/').filter(Boolean).pop() ?? '',
          kind: 'file',
          size: ctx.args.content.kind === 'inline' ? ctx.args.content.bytes.byteLength : ctx.args.content.size,
          mtime: 0,
          metadata: {},
        };
        return { entry: e };
      },
    });
  });
  afterAll(async () => { await rig.teardown(); });

  test('write 2 KiB inline → exceeds 1 KiB/hour cap', async () => {
    const big = new Uint8Array(2048);
    await expect(rig.fs.write('/big.bin', big)).rejects.toBeInstanceOf(QuotaExceededError);
  });
});
