/*  Copyright (c) 2014 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 <stdint.h>

#include <memory>
#include <vector>

#include "absl/types/optional.h"
#include "api/array_view.h"
#include "api/units/data_size.h"
#include "api/units/frequency.h"
#include "api/units/time_delta.h"
#include "modules/video_coding/jitter_estimator.h"
#include "rtc_base/experiments/jitter_upper_bound_experiment.h"
#include "rtc_base/numerics/histogram_percentile_counter.h"
#include "rtc_base/strings/string_builder.h"
#include "rtc_base/time_utils.h"
#include "system_wrappers/include/clock.h"
#include "test/gtest.h"
#include "test/scoped_key_value_config.h"

namespace webrtc {

class TestVCMJitterEstimator : public ::testing::Test {
 protected:
  TestVCMJitterEstimator() : fake_clock_(0) {}

  virtual void SetUp() {
    estimator_ =
        std::make_unique<VCMJitterEstimator>(&fake_clock_, field_trials_);
  }

  SimulatedClock fake_clock_;
  test::ScopedKeyValueConfig field_trials_;
  std::unique_ptr<VCMJitterEstimator> estimator_;
};

// Generates some simple test data in the form of a sawtooth wave.
class ValueGenerator {
 public:
  explicit ValueGenerator(int32_t amplitude)
      : amplitude_(amplitude), counter_(0) {}

  virtual ~ValueGenerator() = default;

  TimeDelta Delay() const {
    return TimeDelta::Millis((counter_ % 11) - 5) * amplitude_;
  }

  DataSize FrameSize() const {
    return DataSize::Bytes(1000 + Delay().ms() / 5);
  }

  void Advance() { ++counter_; }

 private:
  const int32_t amplitude_;
  int64_t counter_;
};

// 5 fps, disable jitter delay altogether.
TEST_F(TestVCMJitterEstimator, TestLowRate) {
  ValueGenerator gen(10);
  TimeDelta time_delta = 1 / Frequency::Hertz(5);
  for (int i = 0; i < 60; ++i) {
    estimator_->UpdateEstimate(gen.Delay(), gen.FrameSize());
    fake_clock_.AdvanceTime(time_delta);
    if (i > 2)
      EXPECT_EQ(estimator_->GetJitterEstimate(0, absl::nullopt),
                TimeDelta::Zero());
    gen.Advance();
  }
}

TEST_F(TestVCMJitterEstimator, TestLowRateDisabled) {
  test::ScopedKeyValueConfig field_trials(
      field_trials_, "WebRTC-ReducedJitterDelayKillSwitch/Enabled/");
  SetUp();

  ValueGenerator gen(10);
  TimeDelta time_delta = 1 / Frequency::Hertz(5);
  for (int i = 0; i < 60; ++i) {
    estimator_->UpdateEstimate(gen.Delay(), gen.FrameSize());
    fake_clock_.AdvanceTime(time_delta);
    if (i > 2)
      EXPECT_GT(estimator_->GetJitterEstimate(0, absl::nullopt),
                TimeDelta::Zero());
    gen.Advance();
  }
}

TEST_F(TestVCMJitterEstimator, TestUpperBound) {
  struct TestContext {
    TestContext()
        : upper_bound(0.0),
          rtt_mult(0),
          rtt_mult_add_cap_ms(absl::nullopt),
          percentiles(1000) {}
    double upper_bound;
    double rtt_mult;
    absl::optional<TimeDelta> rtt_mult_add_cap_ms;
    rtc::HistogramPercentileCounter percentiles;
  };
  std::vector<TestContext> test_cases(4);

  // Large upper bound, rtt_mult = 0, and nullopt for rtt_mult addition cap.
  test_cases[0].upper_bound = 100.0;
  test_cases[0].rtt_mult = 0;
  test_cases[0].rtt_mult_add_cap_ms = absl::nullopt;
  // Small upper bound, rtt_mult = 0, and nullopt for rtt_mult addition cap.
  test_cases[1].upper_bound = 3.5;
  test_cases[1].rtt_mult = 0;
  test_cases[1].rtt_mult_add_cap_ms = absl::nullopt;
  // Large upper bound, rtt_mult = 1, and large rtt_mult addition cap value.
  test_cases[2].upper_bound = 1000.0;
  test_cases[2].rtt_mult = 1.0;
  test_cases[2].rtt_mult_add_cap_ms = TimeDelta::Millis(200);
  // Large upper bound, rtt_mult = 1, and small rtt_mult addition cap value.
  test_cases[3].upper_bound = 1000.0;
  test_cases[3].rtt_mult = 1.0;
  test_cases[3].rtt_mult_add_cap_ms = TimeDelta::Millis(10);

  // Test jitter buffer upper_bound and rtt_mult addition cap sizes.
  for (TestContext& context : test_cases) {
    // Set up field trial and reset jitter estimator.
    char string_buf[64];
    rtc::SimpleStringBuilder ssb(string_buf);
    ssb << JitterUpperBoundExperiment::kJitterUpperBoundExperimentName
        << "/Enabled-" << context.upper_bound << "/";
    test::ScopedKeyValueConfig field_trials(field_trials_, ssb.str());
    SetUp();

    ValueGenerator gen(50);
    TimeDelta time_delta = 1 / Frequency::Hertz(30);
    constexpr TimeDelta kRtt = TimeDelta::Millis(250);
    for (int i = 0; i < 100; ++i) {
      estimator_->UpdateEstimate(gen.Delay(), gen.FrameSize());
      fake_clock_.AdvanceTime(time_delta);
      estimator_->FrameNacked();      // To test rtt_mult.
      estimator_->UpdateRtt(kRtt);    // To test rtt_mult.
      context.percentiles.Add(
          estimator_
              ->GetJitterEstimate(context.rtt_mult, context.rtt_mult_add_cap_ms)
              .ms());
      gen.Advance();
    }
  }

  // Median should be similar after three seconds. Allow 5% error margin.
  uint32_t median_unbound = *test_cases[0].percentiles.GetPercentile(0.5);
  uint32_t median_bounded = *test_cases[1].percentiles.GetPercentile(0.5);
  EXPECT_NEAR(median_unbound, median_bounded, (median_unbound * 5) / 100);

  // Max should be lower for the bounded case.
  uint32_t max_unbound = *test_cases[0].percentiles.GetPercentile(1.0);
  uint32_t max_bounded = *test_cases[1].percentiles.GetPercentile(1.0);
  EXPECT_GT(max_unbound, static_cast<uint32_t>(max_bounded * 1.25));

  // With rtt_mult = 1, max should be lower with small rtt_mult add cap value.
  max_unbound = *test_cases[2].percentiles.GetPercentile(1.0);
  max_bounded = *test_cases[3].percentiles.GetPercentile(1.0);
  EXPECT_GT(max_unbound, static_cast<uint32_t>(max_bounded * 1.25));
}

}  // namespace webrtc
