namespace NATS.Server.Server;

/// <summary>
/// Port of Go's rateCounter utility used for non-blocking allow/deny checks
/// over a fixed one-second interval.
/// Go reference: server/rate_counter.go
/// </summary>
public sealed class RateCounter
{
    private readonly long _limit;
    private long _count;
    private ulong _blocked;
    private DateTime _end;
    private readonly TimeSpan _interval = TimeSpan.FromSeconds(1);
    private readonly Lock _mu = new();

    public RateCounter(long limit)
    {
        _limit = Math.Max(1, limit);
    }

    public bool Allow()
    {
        var now = DateTime.UtcNow;
        lock (_mu)
        {
            if (now > _end)
            {
                _count = 0;
                _end = now + _interval;
            }
            else
            {
                _count++;
            }

            var allow = _count < _limit;
            if (!allow)
                _blocked++;

            return allow;
        }
    }

    public ulong CountBlocked()
    {
        lock (_mu)
        {
            var blocked = _blocked;
            _blocked = 0;
            return blocked;
        }
    }
}
