#include <gtest/gtest.h>

#include <renderive/base/statistics/Rolling_Statistics.hpp>

TEST(RollingStatistics, ComputesWindowDistributionAndEvictsOldSamples) {
    Rolling_Statistics statistics(4);
    for (const double sample : {1.0, 2.0, 3.0, 10.0})
        statistics.add(sample);

    auto snapshot = statistics.snapshot();
    EXPECT_EQ(snapshot.sample_count, 4U);
    EXPECT_DOUBLE_EQ(snapshot.average, 4.0);
    EXPECT_DOUBLE_EQ(snapshot.p50, 2.0);
    EXPECT_DOUBLE_EQ(snapshot.p95, 10.0);
    EXPECT_DOUBLE_EQ(snapshot.p99, 10.0);
    EXPECT_DOUBLE_EQ(snapshot.minimum, 1.0);
    EXPECT_DOUBLE_EQ(snapshot.maximum, 10.0);
    EXPECT_NEAR(snapshot.deviation, 3.5355339059, 1e-9);

    statistics.add(4.0);
    snapshot = statistics.snapshot();
    EXPECT_EQ(snapshot.sample_count, 4U);
    EXPECT_DOUBLE_EQ(snapshot.minimum, 2.0);
    EXPECT_DOUBLE_EQ(snapshot.average, 4.75);
}

TEST(RollingStatistics, ReplacesActiveSampleAndClearsTheWindow) {
    Rolling_Statistics statistics(3);
    statistics.add(5.0);
    statistics.replace_latest(8.0);
    EXPECT_DOUBLE_EQ(statistics.snapshot().p99, 8.0);

    statistics.clear();
    const auto snapshot = statistics.snapshot();
    EXPECT_EQ(snapshot.sample_count, 0U);
    EXPECT_DOUBLE_EQ(snapshot.average, 0.0);
    EXPECT_DOUBLE_EQ(snapshot.p99, 0.0);
}
