namespace SharpChat {
    public class RateLimiter {
        private readonly int Size;
        private readonly int MinimumDelay;
        private readonly int RiskyOffset;
        private readonly long[] TimePoints;

        public RateLimiter(int size, int minDelay, int riskyOffset = 0) {
            if(size < 2)
                throw new ArgumentException("Size is too small.", nameof(size));
            if(minDelay < 1000)
                throw new ArgumentException("Minimum delay is inhuman.", nameof(minDelay));
            if(riskyOffset != 0) {
                if(riskyOffset >= size)
                    throw new ArgumentException("Risky offset may not be greater or equal to the size.", nameof(riskyOffset));
                else if(riskyOffset < 0)
                    throw new ArgumentException("Risky offset may not be negative.", nameof(riskyOffset));
            }

            Size = size;
            MinimumDelay = minDelay;
            RiskyOffset = riskyOffset;
            TimePoints = new long[Size];
        }

        public bool IsRisky => TimePoints[RiskyOffset] != 0 && TimePoints[RiskyOffset + 1] != 0 && TimePoints[RiskyOffset] + MinimumDelay >= TimePoints[Size - 1];
        public bool IsExceeded => TimePoints[0] != 0 && TimePoints[1] != 0 && TimePoints[0] + MinimumDelay >= TimePoints[Size - 1];

        public void Update() {
            for(int i = 1; i < Size; ++i)
                TimePoints[i - 1] = TimePoints[i];
            TimePoints[Size - 1] = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
        }
    }
}