import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';

// We test licenceLimiter directly — it uses an internal Map with TTL.
// We need to reset the module between tests to clear the Map.
// Use vi.isolateModules or reimport with cache busting.

// Because the Map is module-level, we reset it by reloading the module.
// Vitest supports dynamic import with vi.resetModules() for this purpose.

describe('licenceLimiter', () => {
  beforeEach(() => {
    vi.resetModules();
    vi.useRealTimers();
  });

  afterEach(() => {
    vi.useRealTimers();
  });

  it('first request with a new key returns true', async () => {
    const { licenceLimiter } = await import('../lib/rateLimiter.js');
    const result = licenceLimiter('KEY-UNIQUE-001');
    expect(result).toBe(true);
  });

  it('20 successive requests with same key all return true', async () => {
    const { licenceLimiter } = await import('../lib/rateLimiter.js');
    const key = 'KEY-UNIQUE-020';
    for (let i = 0; i < 20; i++) {
      expect(licenceLimiter(key)).toBe(true);
    }
  });

  it('21st request with same key returns false', async () => {
    const { licenceLimiter } = await import('../lib/rateLimiter.js');
    const key = 'KEY-UNIQUE-021';
    for (let i = 0; i < 20; i++) {
      licenceLimiter(key);
    }
    expect(licenceLimiter(key)).toBe(false);
  });

  it('returns true again after the time window expires (simulated)', async () => {
    vi.useFakeTimers();
    const { licenceLimiter } = await import('../lib/rateLimiter.js');
    const key = 'KEY-UNIQUE-RESET';

    // Exhaust the limit
    for (let i = 0; i < 20; i++) {
      licenceLimiter(key);
    }
    expect(licenceLimiter(key)).toBe(false);

    // Advance time by 1 hour + 1ms to simulate window expiration
    vi.advanceTimersByTime(60 * 60 * 1000 + 1);

    // After reset, should be allowed again
    expect(licenceLimiter(key)).toBe(true);
  });

  it('different keys have independent counters', async () => {
    const { licenceLimiter } = await import('../lib/rateLimiter.js');
    const keyA = 'KEY-A-INDEP';
    const keyB = 'KEY-B-INDEP';

    // Exhaust key A
    for (let i = 0; i < 20; i++) {
      licenceLimiter(keyA);
    }
    expect(licenceLimiter(keyA)).toBe(false);

    // Key B should still be allowed
    expect(licenceLimiter(keyB)).toBe(true);
  });
});
