export class SiloFixedWindowRateLimiter {
  private windowStartedAt: number;
  private used = 0;

  constructor(readonly limit: number, readonly windowMs: number, now = Date.now()) {
    if (!Number.isSafeInteger(limit) || limit <= 0) throw new Error("rate limit must be a positive integer");
    if (!Number.isSafeInteger(windowMs) || windowMs <= 0) throw new Error("rate window must be a positive integer");
    this.windowStartedAt = now;
  }

  consume(now = Date.now()): { readonly allowed: true } | { readonly allowed: false; readonly retryAfterSeconds: number } {
    if (now >= this.windowStartedAt + this.windowMs) {
      this.windowStartedAt = now;
      this.used = 0;
    }
    if (this.used >= this.limit) {
      return {
        allowed: false,
        retryAfterSeconds: Math.max(1, Math.ceil((this.windowStartedAt + this.windowMs - now) / 1000)),
      };
    }
    this.used += 1;
    return { allowed: true };
  }
}
