/*
 *  Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "video/stats_counter.h"

#include <cstdint>

#include "system_wrappers/include/clock.h"
#include "test/gtest.h"

namespace webrtc {
namespace {
constexpr int kDefaultProcessIntervalMs = 2000;
constexpr uint32_t kStreamId = 123456;

class StatsCounterObserverImpl : public StatsCounterObserver {
 public:
  StatsCounterObserverImpl() : num_calls_(0), last_sample_(-1) {}
  void OnMetricUpdated(int sample) override {
    ++num_calls_;
    last_sample_ = sample;
  }
  int num_calls_;
  int last_sample_;
};
}  // namespace

class StatsCounterTest : public ::testing::Test {
 protected:
  StatsCounterTest() : clock_(1234) {}

  void AddSampleAndAdvance(int sample, int interval_ms, AvgCounter* counter) {
    counter->Add(sample);
    clock_.AdvanceTimeMilliseconds(interval_ms);
  }

  void SetSampleAndAdvance(int sample,
                           int interval_ms,
                           RateAccCounter* counter) {
    counter->Set(sample, kStreamId);
    clock_.AdvanceTimeMilliseconds(interval_ms);
  }

  void VerifyStatsIsNotSet(const AggregatedStats& stats) {
    EXPECT_EQ(0, stats.num_samples);
    EXPECT_EQ(-1, stats.min);
    EXPECT_EQ(-1, stats.max);
    EXPECT_EQ(-1, stats.average);
  }

  SimulatedClock clock_;
};

TEST_F(StatsCounterTest, NoSamples) {
  AvgCounter counter(&clock_, nullptr, false);
  VerifyStatsIsNotSet(counter.GetStats());
}

TEST_F(StatsCounterTest, TestRegisterObserver) {
  StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
  const int kSample = 22;
  AvgCounter counter(&clock_, observer, false);
  AddSampleAndAdvance(kSample, kDefaultProcessIntervalMs, &counter);
  // Trigger process (sample included in next interval).
  counter.Add(111);
  EXPECT_EQ(1, observer->num_calls_);
}

TEST_F(StatsCounterTest, HasSample) {
  AvgCounter counter(&clock_, nullptr, false);
  EXPECT_FALSE(counter.HasSample());
  counter.Add(1);
  EXPECT_TRUE(counter.HasSample());
}

TEST_F(StatsCounterTest, VerifyProcessInterval) {
  StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
  AvgCounter counter(&clock_, observer, false);
  counter.Add(4);
  clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs - 1);
  // Try trigger process (interval has not passed).
  counter.Add(8);
  EXPECT_EQ(0, observer->num_calls_);
  VerifyStatsIsNotSet(counter.GetStats());
  // Make process interval pass.
  clock_.AdvanceTimeMilliseconds(1);
  // Trigger process (sample included in next interval).
  counter.Add(111);
  EXPECT_EQ(1, observer->num_calls_);
  EXPECT_EQ(6, observer->last_sample_);
  // Aggregated stats.
  AggregatedStats stats = counter.GetStats();
  EXPECT_EQ(1, stats.num_samples);
}

TEST_F(StatsCounterTest, TestMetric_AvgCounter) {
  StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
  AvgCounter counter(&clock_, observer, false);
  counter.Add(4);
  counter.Add(8);
  counter.Add(9);
  clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs);
  // Trigger process (sample included in next interval).
  counter.Add(111);
  // Average per interval.
  EXPECT_EQ(1, observer->num_calls_);
  EXPECT_EQ(7, observer->last_sample_);
  // Aggregated stats.
  AggregatedStats stats = counter.GetStats();
  EXPECT_EQ(1, stats.num_samples);
  EXPECT_EQ(7, stats.min);
  EXPECT_EQ(7, stats.max);
  EXPECT_EQ(7, stats.average);
}

TEST_F(StatsCounterTest, TestMetric_MaxCounter) {
  const int64_t kProcessIntervalMs = 1000;
  StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
  MaxCounter counter(&clock_, observer, kProcessIntervalMs);
  counter.Add(4);
  counter.Add(9);
  counter.Add(8);
  clock_.AdvanceTimeMilliseconds(kProcessIntervalMs);
  // Trigger process (sample included in next interval).
  counter.Add(111);
  // Average per interval.
  EXPECT_EQ(1, observer->num_calls_);
  EXPECT_EQ(9, observer->last_sample_);
  // Aggregated stats.
  AggregatedStats stats = counter.GetStats();
  EXPECT_EQ(1, stats.num_samples);
  EXPECT_EQ(9, stats.min);
  EXPECT_EQ(9, stats.max);
  EXPECT_EQ(9, stats.average);
}

TEST_F(StatsCounterTest, TestMetric_PercentCounter) {
  StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
  PercentCounter counter(&clock_, observer);
  counter.Add(true);
  counter.Add(false);
  clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs);
  // Trigger process (sample included in next interval).
  counter.Add(false);
  // Percentage per interval.
  EXPECT_EQ(1, observer->num_calls_);
  EXPECT_EQ(50, observer->last_sample_);
  // Aggregated stats.
  AggregatedStats stats = counter.GetStats();
  EXPECT_EQ(1, stats.num_samples);
  EXPECT_EQ(50, stats.min);
  EXPECT_EQ(50, stats.max);
}

TEST_F(StatsCounterTest, TestMetric_PermilleCounter) {
  StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
  PermilleCounter counter(&clock_, observer);
  counter.Add(true);
  counter.Add(false);
  clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs);
  // Trigger process (sample included in next interval).
  counter.Add(false);
  // Permille per interval.
  EXPECT_EQ(1, observer->num_calls_);
  EXPECT_EQ(500, observer->last_sample_);
  // Aggregated stats.
  AggregatedStats stats = counter.GetStats();
  EXPECT_EQ(1, stats.num_samples);
  EXPECT_EQ(500, stats.min);
  EXPECT_EQ(500, stats.max);
}

TEST_F(StatsCounterTest, TestMetric_RateCounter) {
  StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
  RateCounter counter(&clock_, observer, true);
  counter.Add(186);
  counter.Add(350);
  counter.Add(22);
  clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs);
  // Trigger process (sample included in next interval).
  counter.Add(111);
  // Rate per interval, (186 + 350 + 22) / 2 sec = 279 samples/sec
  EXPECT_EQ(1, observer->num_calls_);
  EXPECT_EQ(279, observer->last_sample_);
  // Aggregated stats.
  AggregatedStats stats = counter.GetStats();
  EXPECT_EQ(1, stats.num_samples);
  EXPECT_EQ(279, stats.min);
  EXPECT_EQ(279, stats.max);
}

TEST_F(StatsCounterTest, TestMetric_RateAccCounter) {
  StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
  RateAccCounter counter(&clock_, observer, true);
  counter.Set(175, kStreamId);
  counter.Set(188, kStreamId);
  clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs);
  // Trigger process (sample included in next interval).
  counter.Set(192, kStreamId);
  // Rate per interval: (188 - 0) / 2 sec = 94 samples/sec
  EXPECT_EQ(1, observer->num_calls_);
  EXPECT_EQ(94, observer->last_sample_);
  // Aggregated stats.
  AggregatedStats stats = counter.GetStats();
  EXPECT_EQ(1, stats.num_samples);
  EXPECT_EQ(94, stats.min);
  EXPECT_EQ(94, stats.max);
}

TEST_F(StatsCounterTest, TestMetric_RateAccCounterWithSetLast) {
  StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
  RateAccCounter counter(&clock_, observer, true);
  counter.SetLast(98, kStreamId);
  counter.Set(175, kStreamId);
  counter.Set(188, kStreamId);
  clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs);
  // Trigger process (sample included in next interval).
  counter.Set(192, kStreamId);
  // Rate per interval: (188 - 98) / 2 sec = 45 samples/sec
  EXPECT_EQ(1, observer->num_calls_);
  EXPECT_EQ(45, observer->last_sample_);
}

TEST_F(StatsCounterTest, TestMetric_RateAccCounterWithMultipleStreamIds) {
  StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
  RateAccCounter counter(&clock_, observer, true);
  counter.Set(175, kStreamId);
  counter.Set(188, kStreamId);
  counter.Set(100, kStreamId + 1);
  clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs);
  // Trigger process (sample included in next interval).
  counter.Set(150, kStreamId + 1);
  // Rate per interval: ((188 - 0) + (100 - 0)) / 2 sec = 144 samples/sec
  EXPECT_EQ(1, observer->num_calls_);
  EXPECT_EQ(144, observer->last_sample_);
  clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs);
  // Trigger process (sample included in next interval).
  counter.Set(198, kStreamId);
  // Rate per interval: (0 + (150 - 100)) / 2 sec = 25 samples/sec
  EXPECT_EQ(2, observer->num_calls_);
  EXPECT_EQ(25, observer->last_sample_);
  clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs);
  // Trigger process (sample included in next interval).
  counter.Set(200, kStreamId);
  // Rate per interval: ((198 - 188) + (0)) / 2 sec = 5 samples/sec
  EXPECT_EQ(3, observer->num_calls_);
  EXPECT_EQ(5, observer->last_sample_);
  // Aggregated stats.
  AggregatedStats stats = counter.GetStats();
  EXPECT_EQ(3, stats.num_samples);
  EXPECT_EQ(5, stats.min);
  EXPECT_EQ(144, stats.max);
}

TEST_F(StatsCounterTest, TestGetStats_MultipleIntervals) {
  AvgCounter counter(&clock_, nullptr, false);
  const int kSample1 = 1;
  const int kSample2 = 5;
  const int kSample3 = 8;
  const int kSample4 = 11;
  const int kSample5 = 50;
  AddSampleAndAdvance(kSample1, kDefaultProcessIntervalMs, &counter);
  AddSampleAndAdvance(kSample2, kDefaultProcessIntervalMs, &counter);
  AddSampleAndAdvance(kSample3, kDefaultProcessIntervalMs, &counter);
  AddSampleAndAdvance(kSample4, kDefaultProcessIntervalMs, &counter);
  AddSampleAndAdvance(kSample5, kDefaultProcessIntervalMs, &counter);
  // Trigger process (sample included in next interval).
  counter.Add(111);
  AggregatedStats stats = counter.GetStats();
  EXPECT_EQ(5, stats.num_samples);
  EXPECT_EQ(kSample1, stats.min);
  EXPECT_EQ(kSample5, stats.max);
  EXPECT_EQ(15, stats.average);
}

TEST_F(StatsCounterTest, TestGetStatsTwice) {
  const int kSample1 = 4;
  const int kSample2 = 7;
  AvgCounter counter(&clock_, nullptr, false);
  AddSampleAndAdvance(kSample1, kDefaultProcessIntervalMs, &counter);
  // Trigger process (sample included in next interval).
  counter.Add(kSample2);
  AggregatedStats stats = counter.GetStats();
  EXPECT_EQ(1, stats.num_samples);
  EXPECT_EQ(kSample1, stats.min);
  EXPECT_EQ(kSample1, stats.max);
  // Trigger process (sample included in next interval).
  clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs);
  counter.Add(111);
  stats = counter.GetStats();
  EXPECT_EQ(2, stats.num_samples);
  EXPECT_EQ(kSample1, stats.min);
  EXPECT_EQ(kSample2, stats.max);
  EXPECT_EQ(6, stats.average);
}

TEST_F(StatsCounterTest, TestRateAccCounter_NegativeRateIgnored) {
  StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
  const int kSample1 = 200;  //  200 / 2 sec
  const int kSample2 = 100;  // -100 / 2 sec - negative ignored
  const int kSample3 = 700;  //  600 / 2 sec
  RateAccCounter counter(&clock_, observer, true);
  SetSampleAndAdvance(kSample1, kDefaultProcessIntervalMs, &counter);
  SetSampleAndAdvance(kSample2, kDefaultProcessIntervalMs, &counter);
  SetSampleAndAdvance(kSample3, kDefaultProcessIntervalMs, &counter);
  EXPECT_EQ(1, observer->num_calls_);
  EXPECT_EQ(100, observer->last_sample_);
  // Trigger process (sample included in next interval).
  counter.Set(2000, kStreamId);
  EXPECT_EQ(2, observer->num_calls_);
  EXPECT_EQ(300, observer->last_sample_);
  // Aggregated stats.
  AggregatedStats stats = counter.GetStats();
  EXPECT_EQ(2, stats.num_samples);
  EXPECT_EQ(100, stats.min);
  EXPECT_EQ(300, stats.max);
  EXPECT_EQ(200, stats.average);
}

TEST_F(StatsCounterTest, TestAvgCounter_IntervalsWithoutSamplesIncluded) {
  // Samples: | 6 | x | x | 8 |  // x: empty interval
  // Stats:   | 6 | 6 | 6 | 8 |  // x -> last value reported
  StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
  AvgCounter counter(&clock_, observer, true);
  AddSampleAndAdvance(6, kDefaultProcessIntervalMs * 4 - 1, &counter);
  // Trigger process (sample included in next interval).
  counter.Add(8);
  // [6:3], 3 intervals passed (2 without samples -> last value reported).
  AggregatedStats stats = counter.ProcessAndGetStats();
  EXPECT_EQ(3, stats.num_samples);
  EXPECT_EQ(6, stats.min);
  EXPECT_EQ(6, stats.max);
  // Make next interval pass and verify stats: [6:3],[8:1]
  clock_.AdvanceTimeMilliseconds(1);
  counter.ProcessAndGetStats();
  EXPECT_EQ(4, observer->num_calls_);
  EXPECT_EQ(8, observer->last_sample_);
}

TEST_F(StatsCounterTest, TestAvgCounter_WithPause) {
  // Samples: | 6 | x | x | x | - | 22 | x  |  // x: empty interval, -: paused
  // Stats:   | 6 | 6 | 6 | 6 | - | 22 | 22 |  // x -> last value reported
  StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
  AvgCounter counter(&clock_, observer, true);
  // Add sample and advance 3 intervals (2 w/o samples -> last value reported).
  AddSampleAndAdvance(6, kDefaultProcessIntervalMs * 4 - 1, &counter);
  // Trigger process and verify stats: [6:3]
  counter.ProcessAndGetStats();
  EXPECT_EQ(3, observer->num_calls_);
  EXPECT_EQ(6, observer->last_sample_);
  // Make next interval pass (1 without samples).
  // Process and pause. Verify stats: [6:4].
  clock_.AdvanceTimeMilliseconds(1);
  counter.ProcessAndPause();
  EXPECT_EQ(4, observer->num_calls_);  // Last value reported.
  EXPECT_EQ(6, observer->last_sample_);
  // Make next interval pass (1 without samples -> ignored while paused).
  clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs * 2 - 1);
  counter.Add(22);  // Stops pause.
  EXPECT_EQ(4, observer->num_calls_);
  EXPECT_EQ(6, observer->last_sample_);
  // Make next interval pass, [6:4][22:1]
  clock_.AdvanceTimeMilliseconds(1);
  counter.ProcessAndGetStats();
  EXPECT_EQ(5, observer->num_calls_);
  EXPECT_EQ(22, observer->last_sample_);
  // Make 1 interval pass (1 w/o samples -> pause stopped, last value reported).
  clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs);
  counter.ProcessAndGetStats();
  EXPECT_EQ(6, observer->num_calls_);
  EXPECT_EQ(22, observer->last_sample_);
}

TEST_F(StatsCounterTest, TestRateAccCounter_AddSampleStopsPause) {
  // Samples: | 12 | 24 |  // -: paused
  // Stats:   | 6  | 6  |
  StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
  RateAccCounter counter(&clock_, observer, true);
  // Add sample and advance 1 intervals.
  counter.Set(12, kStreamId);
  clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs);
  // Trigger process and verify stats: [6:1]
  counter.ProcessAndPause();
  EXPECT_EQ(1, observer->num_calls_);
  EXPECT_EQ(6, observer->last_sample_);
  // Add sample and advance 1 intervals.
  counter.Set(24, kStreamId);  // Pause stopped.
  clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs);
  counter.ProcessAndGetStats();
  EXPECT_EQ(2, observer->num_calls_);
  EXPECT_EQ(6, observer->last_sample_);
}

TEST_F(StatsCounterTest, TestRateAccCounter_AddSameSampleDoesNotStopPause) {
  // Samples: | 12 | 12 | 24 |  // -: paused
  // Stats:   | 6  | -  | 6  |
  StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
  RateAccCounter counter(&clock_, observer, true);
  // Add sample and advance 1 intervals.
  counter.Set(12, kStreamId);
  clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs);
  // Trigger process and verify stats: [6:1]
  counter.ProcessAndPause();
  EXPECT_EQ(1, observer->num_calls_);
  EXPECT_EQ(6, observer->last_sample_);
  // Add same sample and advance 1 intervals.
  counter.Set(12, kStreamId);  // Pause not stopped.
  clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs);
  counter.ProcessAndGetStats();
  EXPECT_EQ(1, observer->num_calls_);
  EXPECT_EQ(6, observer->last_sample_);
  // Add new sample and advance 1 intervals.
  counter.Set(24, kStreamId);  // Pause stopped.
  clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs);
  counter.ProcessAndGetStats();
  EXPECT_EQ(2, observer->num_calls_);
  EXPECT_EQ(6, observer->last_sample_);
}

TEST_F(StatsCounterTest, TestRateAccCounter_PauseAndStopPause) {
  // Samples: | 12 | 12 | 12 |  // -: paused
  // Stats:   | 6  | -  | 0  |
  StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
  RateAccCounter counter(&clock_, observer, true);
  // Add sample and advance 1 intervals.
  counter.Set(12, kStreamId);
  clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs);
  // Trigger process and verify stats: [6:1]
  counter.ProcessAndPause();
  EXPECT_EQ(1, observer->num_calls_);
  EXPECT_EQ(6, observer->last_sample_);
  // Add same sample and advance 1 intervals.
  counter.Set(12, kStreamId);  // Pause not stopped.
  clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs);
  counter.ProcessAndGetStats();
  EXPECT_EQ(1, observer->num_calls_);
  EXPECT_EQ(6, observer->last_sample_);
  // Stop pause, add sample and advance 1 intervals.
  counter.ProcessAndStopPause();
  counter.Set(12, kStreamId);
  clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs);
  counter.ProcessAndGetStats();
  EXPECT_EQ(2, observer->num_calls_);
  EXPECT_EQ(0, observer->last_sample_);
}

TEST_F(StatsCounterTest, TestAvgCounter_WithoutMinPauseTimePassed) {
  // Samples: | 6 | 2 | - |  // x: empty interval, -: paused
  // Stats:   | 6 | 2 | - |  // x -> last value reported
  StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
  AvgCounter counter(&clock_, observer, true);
  // Add sample and advance 1 intervals.
  AddSampleAndAdvance(6, kDefaultProcessIntervalMs, &counter);
  // Process and pause. Verify stats: [6:1].
  const int64_t kMinMs = 500;
  counter.ProcessAndPauseForDuration(kMinMs);
  EXPECT_EQ(1, observer->num_calls_);  // Last value reported.
  EXPECT_EQ(6, observer->last_sample_);
  // Min pause time has not pass.
  clock_.AdvanceTimeMilliseconds(kMinMs - 1);
  counter.Add(2);  // Pause not stopped.
  // Make two intervals pass (1 without samples -> ignored while paused).
  clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs * 2 - (kMinMs - 1));
  counter.ProcessAndGetStats();
  EXPECT_EQ(2, observer->num_calls_);
  EXPECT_EQ(2, observer->last_sample_);
}

TEST_F(StatsCounterTest, TestAvgCounter_WithMinPauseTimePassed) {
  // Samples: | 6 | 2 | x |  // x: empty interval, -: paused
  // Stats:   | 6 | 2 | 2 |  // x -> last value reported
  StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
  AvgCounter counter(&clock_, observer, true);
  // Add sample and advance 1 intervals.
  AddSampleAndAdvance(6, kDefaultProcessIntervalMs, &counter);
  // Process and pause. Verify stats: [6:1].
  const int64_t kMinMs = 500;
  counter.ProcessAndPauseForDuration(kMinMs);
  EXPECT_EQ(1, observer->num_calls_);  // Last value reported.
  EXPECT_EQ(6, observer->last_sample_);
  // Make min pause time pass.
  clock_.AdvanceTimeMilliseconds(kMinMs);
  counter.Add(2);  // Stop pause.
  // Make two intervals pass (1 without samples -> last value reported).
  clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs * 2 - kMinMs);
  counter.ProcessAndGetStats();
  EXPECT_EQ(3, observer->num_calls_);
  EXPECT_EQ(2, observer->last_sample_);
}

TEST_F(StatsCounterTest, TestRateCounter_IntervalsWithoutSamplesIgnored) {
  // Samples: | 50 | x | 20 |  // x: empty interval
  // Stats:   | 25 | x | 10 |  // x -> ignored
  const bool kIncludeEmptyIntervals = false;
  StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
  const int kSample1 = 50;  //  50 / 2 sec
  const int kSample2 = 20;  //  20 / 2 sec
  RateCounter counter(&clock_, observer, kIncludeEmptyIntervals);
  counter.Add(kSample1);
  clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs * 3 - 1);
  // Trigger process (sample included in next interval).
  counter.Add(kSample2);
  // [25:1], 2 intervals passed (1 without samples -> ignored).
  EXPECT_EQ(1, observer->num_calls_);
  EXPECT_EQ(25, observer->last_sample_);
  // Make next interval pass and verify stats: [10:1],[25:1]
  clock_.AdvanceTimeMilliseconds(1);
  counter.ProcessAndGetStats();
  EXPECT_EQ(2, observer->num_calls_);
  EXPECT_EQ(10, observer->last_sample_);
}

TEST_F(StatsCounterTest, TestRateCounter_IntervalsWithoutSamplesIncluded) {
  // Samples: | 50 | x | 20 |  // x: empty interval
  // Stats:   | 25 | 0 | 10 |  // x -> zero reported
  const bool kIncludeEmptyIntervals = true;
  StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
  const int kSample1 = 50;  //  50 / 2 sec
  const int kSample2 = 20;  //  20 / 2 sec
  RateCounter counter(&clock_, observer, kIncludeEmptyIntervals);
  counter.Add(kSample1);
  clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs * 3 - 1);
  // Trigger process (sample included in next interval).
  counter.Add(kSample2);
  // [0:1],[25:1], 2 intervals passed (1 without samples -> zero reported).
  EXPECT_EQ(2, observer->num_calls_);
  EXPECT_EQ(0, observer->last_sample_);
  // Make last interval pass and verify stats: [0:1],[10:1],[25:1]
  clock_.AdvanceTimeMilliseconds(1);
  AggregatedStats stats = counter.ProcessAndGetStats();
  EXPECT_EQ(25, stats.max);
  EXPECT_EQ(3, observer->num_calls_);
  EXPECT_EQ(10, observer->last_sample_);
}

TEST_F(StatsCounterTest, TestRateAccCounter_IntervalsWithoutSamplesIncluded) {
  // Samples: | 12 | x | x | x | 60 |  // x: empty interval
  // Stats:   | 6  | 0 | 0 | 0 | 24 |  // x -> zero reported
  StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
  RateAccCounter counter(&clock_, observer, true);
  VerifyStatsIsNotSet(counter.ProcessAndGetStats());
  // Advance one interval and verify stats.
  clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs);
  VerifyStatsIsNotSet(counter.ProcessAndGetStats());
  // Add sample and advance 3 intervals (2 w/o samples -> zero reported).
  counter.Set(12, kStreamId);
  clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs * 4 - 1);
  // Trigger process and verify stats: [0:2][6:1]
  counter.ProcessAndGetStats();
  EXPECT_EQ(3, observer->num_calls_);
  EXPECT_EQ(0, observer->last_sample_);
  // Make next interval pass (1 w/o samples -> zero reported), [0:3][6:1]
  clock_.AdvanceTimeMilliseconds(1);
  counter.ProcessAndGetStats();
  EXPECT_EQ(4, observer->num_calls_);
  EXPECT_EQ(0, observer->last_sample_);
  // Insert sample and advance non-complete interval, no change, [0:3][6:1]
  clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs - 1);
  counter.Set(60, kStreamId);
  EXPECT_EQ(4, observer->num_calls_);
  // Make next interval pass, [0:3][6:1][24:1]
  clock_.AdvanceTimeMilliseconds(1);
  AggregatedStats stats = counter.ProcessAndGetStats();
  EXPECT_EQ(5, observer->num_calls_);
  EXPECT_EQ(24, observer->last_sample_);
  EXPECT_EQ(6, stats.average);
}

TEST_F(StatsCounterTest, TestRateAccCounter_IntervalsWithoutSamplesIgnored) {
  // Samples: | 12 | x | x | x | 60 |  // x: empty interval
  // Stats:   | 6  | x | x | x | 24 |  // x -> ignored
  StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
  RateAccCounter counter(&clock_, observer, false);
  // Add sample and advance 3 intervals (2 w/o samples -> ignored).
  counter.Set(12, kStreamId);
  clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs * 4 - 1);
  // Trigger process and verify stats: [6:1]
  counter.ProcessAndGetStats();
  EXPECT_EQ(1, observer->num_calls_);
  EXPECT_EQ(6, observer->last_sample_);
  // Make next interval pass (1 w/o samples -> ignored), [6:1]
  clock_.AdvanceTimeMilliseconds(1);
  counter.ProcessAndGetStats();
  EXPECT_EQ(1, observer->num_calls_);
  // Insert sample and advance non-complete interval, no change, [6:1]
  clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs - 1);
  counter.Set(60, kStreamId);
  counter.ProcessAndGetStats();
  EXPECT_EQ(1, observer->num_calls_);
  // Make next interval pass, [6:1][24:1]
  clock_.AdvanceTimeMilliseconds(1);
  counter.ProcessAndGetStats();
  EXPECT_EQ(2, observer->num_calls_);
  EXPECT_EQ(24, observer->last_sample_);
}

}  // namespace webrtc
