import { describe, it, expect, beforeEach } from 'bun:test';
import { RateLimiter } from '../../../src/services/rate-limit';

describe('RateLimiter - token bucket básico', () => {
  beforeEach(() => {
    RateLimiter.reset();
    // No dependemos de NODE_ENV aquí; testea la clase aislada.
    process.env.RATE_LIMIT_PER_MIN = '15';
    process.env.RATE_LIMIT_BURST = '15';
  });

  it('permite hasta el burst inicial y bloquea al exceder', () => {
    const user = '1234567890';
    const t0 = 0;

    // 15 primeros deben pasar
    for (let i = 0; i < 15; i++) {
      const ok = RateLimiter.checkAndConsume(user, t0);
      expect(ok).toBe(true);
    }

    // 16º sin tiempo transcurrido debe bloquear
    const denied = RateLimiter.checkAndConsume(user, t0);
    expect(denied).toBe(false);
  });

  it('recupera tokens con el tiempo (refill lineal por minuto)', () => {
    const user = '1234567890';
    const t0 = 0;

    // Agotar bucket
    for (let i = 0; i < 15; i++) {
      expect(RateLimiter.checkAndConsume(user, t0)).toBe(true);
    }
    expect(RateLimiter.checkAndConsume(user, t0)).toBe(false); // agotado

    // Tras 60s debe haberse recuperado capacidad suficiente para permitir de nuevo
    const t1 = 60_000;
    expect(RateLimiter.checkAndConsume(user, t1)).toBe(true);

    // Y puede consumir varios más (hasta ~15 por minuto)
    let count = 1;
    while (RateLimiter.checkAndConsume(user, t1)) {
      count++;
      if (count > 20) break; // seguridad
    }
    expect(count).toBeGreaterThan(1);
  });

  it('shouldNotify limita el aviso a como mucho 1/min por usuario', () => {
    const user = 'u1';
    const t0 = 0;
    expect(RateLimiter.shouldNotify(user, t0)).toBe(true);  // primera vez notifica
    expect(RateLimiter.shouldNotify(user, t0 + 10_000)).toBe(false); // dentro de la ventana
    expect(RateLimiter.shouldNotify(user, t0 + 60_000)).toBe(true); // pasado el cooldown
  });
});
