namespace NATS.Server.Tls;

public sealed class TlsRateLimiter : IDisposable
{
    private readonly SemaphoreSlim _semaphore;
    private readonly Timer _refillTimer;
    private readonly int _tokensPerSecond;

    public TlsRateLimiter(long tokensPerSecond)
    {
        _tokensPerSecond = (int)Math.Max(1, tokensPerSecond);
        _semaphore = new SemaphoreSlim(_tokensPerSecond, _tokensPerSecond);
        _refillTimer = new Timer(Refill, null, TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1));
    }

    private void Refill(object? state)
    {
        int toRelease = _tokensPerSecond - _semaphore.CurrentCount;
        if (toRelease > 0) _semaphore.Release(toRelease);
    }

    public Task WaitAsync(CancellationToken ct) => _semaphore.WaitAsync(ct);

    public void Dispose() { _refillTimer.Dispose(); _semaphore.Dispose(); }
}
