/*  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/field_trial.h"
#include "test/gtest.h"

namespace webrtc {

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

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

  SimulatedClock fake_clock_;
  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::ScopedFieldTrials 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::ScopedFieldTrials 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
