#include "stats_buffer.h"

#include <library/cpp/testing/unittest/registar.h>
#include <util/generic/xrange.h>

Y_UNIT_TEST_SUITE(TStatsBufferTest) {
    Y_UNIT_TEST(SimpleTest) {
        TStatsBuffer buf(
            TInstant::Seconds(100),
            10,
            TDuration::Seconds(5),  // interval size
            TDuration::Seconds(60), // max stats age
            TDuration::Seconds(30)  // max write age
        );
        auto noopVisitor = [](const TStatsBuffer::TStats&) { return; };
        auto addOneVisitor = [](TStatsBuffer::TStats& st) {
            st[0] += 1;
            st[9] += 1;
        };

        // wierd write into the future
        UNIT_ASSERT_VALUES_EQUAL(
            buf.VisitWritableStats(
                TInstant::Seconds(100),
                TInstant::Seconds(110),
                noopVisitor
            ), false
        );

        // write past the write limit
        UNIT_ASSERT_VALUES_EQUAL(
            buf.VisitWritableStats(
                TInstant::Seconds(100),
                TInstant::Seconds(50),
                noopVisitor
            ), false
        );

        // read for a too recent value
        UNIT_ASSERT_VALUES_EQUAL(
            buf.VisitReadableStats(
                TInstant::Seconds(100),
                TInstant::Seconds(80),
                noopVisitor
            ), false
        );

        for (size_t i : xrange(10)) {
            UNIT_ASSERT_VALUES_EQUAL(
                buf.VisitWritableStats(
                    TInstant::Seconds(125 + 5 * i),
                    TInstant::Seconds(100 + 5 * i),
                    addOneVisitor
                ), true
            );
        }

        UNIT_ASSERT_VALUES_EQUAL(
            buf.VisitReadableStats(
                TInstant::Seconds(125 + 50),
                TInstant::Seconds(100 + 40),
                [](const TStatsBuffer::TStats& s) {
                    UNIT_ASSERT_VALUES_EQUAL(s[0], 1);
                    UNIT_ASSERT_VALUES_EQUAL(s[1], 0);
                    UNIT_ASSERT_VALUES_EQUAL(s[9], 1);
                }
            ), true
        );
    }
};
