#pragma once

#include <util/generic/vector.h>
#include <util/datetime/base.h>

namespace NModAntiDDOS {
    class TRateCounter {
    public:
        TRateCounter() noexcept
            : Cur_(0) {
        }

        void Init(double maxRate) noexcept {
            maxRate = Max(maxRate, 1.);
            const size_t sz = Min<size_t>((size_t)(maxRate * 3), 10000);

            Times_.resize(sz);

            for (size_t i = 0; i < sz; ++i) {
                Times_[i] = TInstant::Zero();
            }

            Cur_ = 0;
        }

        double CalculateRate(TInstant reqStart) noexcept {
            reqStart = Max(reqStart, Times_[(Cur_ + Times_.size() - 1) % Times_.size()]);
            return (double) TDuration::Seconds(Times_.size()).GetValue() /
                Max(reqStart - Times_[Cur_], TDuration::MicroSeconds(1)).GetValue();
        }

        void AddRequest(TInstant reqStart) noexcept {
            Times_[Cur_] = Max(reqStart, Times_[(Cur_ + Times_.size() - 1) % Times_.size()]);
            Cur_ = (Cur_ + 1) % Times_.size();
        }

    private:
        TVector<TInstant> Times_;
        size_t Cur_;
    };
}
