/*  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 "video/timing/jitter_estimator.h"

#include <cstdint>
#include <optional>
#include <string>

#include "api/field_trials.h"
#include "api/units/data_size.h"
#include "api/units/frequency.h"
#include "api/units/time_delta.h"
#include "system_wrappers/include/clock.h"
#include "test/create_test_field_trials.h"
#include "test/gtest.h"

namespace webrtc {
namespace {

constexpr TimeDelta kInterArrivalTime = TimeDelta::Millis(33);
// From jitter_estimator.cc.
constexpr double kRttMult = 0.9;
constexpr TimeDelta kRttMultAddCap = TimeDelta::Millis(200);

// 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_;
};

class JitterEstimatorTest : public ::testing::Test {
 protected:
  explicit JitterEstimatorTest(const std::string& field_trials)
      : fake_clock_(0),
        field_trials_(CreateTestFieldTrials(field_trials)),
        estimator_(&fake_clock_, field_trials_) {}
  JitterEstimatorTest() : JitterEstimatorTest("") {}
  ~JitterEstimatorTest() override {}

  void Run(int duration_s, int framerate_fps, ValueGenerator& gen) {
    TimeDelta tick = 1 / Frequency::Hertz(framerate_fps);
    for (int i = 0; i < duration_s * framerate_fps; ++i) {
      estimator_.UpdateEstimate(gen.Delay(), gen.FrameSize());
      fake_clock_.AdvanceTime(tick);
      gen.Advance();
    }
  }

  SimulatedClock fake_clock_;
  FieldTrials field_trials_;
  JitterEstimator estimator_;
};

TEST_F(JitterEstimatorTest, SteadyStateConvergence) {
  ValueGenerator gen(10);
  Run(/*duration_s=*/60, /*framerate_fps=*/30, gen);
  EXPECT_EQ(estimator_.GetEstimate().ms(), 54);
}

TEST_F(JitterEstimatorTest,
       SizeOutlierIsNotRejectedAndIncreasesJitterEstimate) {
  ValueGenerator gen(10);

  // Steady state.
  Run(/*duration_s=*/60, /*framerate_fps=*/30, gen);
  TimeDelta steady_state_jitter = estimator_.GetEstimate();

  // A single outlier frame size...
  estimator_.UpdateEstimate(gen.Delay(), 10 * gen.FrameSize());
  TimeDelta outlier_jitter = estimator_.GetEstimate();

  // ...changes the estimate.
  EXPECT_GT(outlier_jitter.ms(), 1.25 * steady_state_jitter.ms());
}

TEST_F(JitterEstimatorTest, LowFramerateDisablesJitterEstimator) {
  ValueGenerator gen(10);
  // At 5 fps, we disable jitter delay altogether.
  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_.GetEstimate(), TimeDelta::Zero());
    gen.Advance();
  }
}

// By default, the `JitterEstimator` is not robust against single large frames.
TEST_F(JitterEstimatorTest, Single2xFrameSizeImpactsJitterEstimate) {
  ValueGenerator gen(10);

  // Steady state.
  Run(/*duration_s=*/60, /*framerate_fps=*/30, gen);
  TimeDelta steady_state_jitter = estimator_.GetEstimate();

  // A single outlier frame size...
  estimator_.UpdateEstimate(gen.Delay(), 2 * gen.FrameSize());
  TimeDelta outlier_jitter = estimator_.GetEstimate();

  // ...impacts the estimate.
  EXPECT_GT(outlier_jitter.ms(), steady_state_jitter.ms());
}

// Under the default config, congested frames are used when calculating the
// noise variance, meaning that they will impact the final jitter estimate.
TEST_F(JitterEstimatorTest, CongestedFrameImpactsJitterEstimate) {
  ValueGenerator gen(10);

  // Steady state.
  Run(/*duration_s=*/10, /*framerate_fps=*/30, gen);
  TimeDelta steady_state_jitter = estimator_.GetEstimate();

  // Congested frame...
  estimator_.UpdateEstimate(-10 * gen.Delay(), 0.1 * gen.FrameSize());
  TimeDelta outlier_jitter = estimator_.GetEstimate();

  // ...impacts the estimate.
  EXPECT_GT(outlier_jitter.ms(), steady_state_jitter.ms());
}

TEST_F(JitterEstimatorTest, EmptyFieldTrialsParsesToUnsetConfig) {
  JitterEstimator::Config config = estimator_.GetConfigForTest();
  EXPECT_FALSE(config.avg_frame_size_median);
  EXPECT_FALSE(config.max_frame_size_percentile.has_value());
  EXPECT_FALSE(config.frame_size_window.has_value());
  EXPECT_FALSE(config.num_stddev_delay_clamp.has_value());
  EXPECT_FALSE(config.num_stddev_delay_outlier.has_value());
  EXPECT_FALSE(config.num_stddev_size_outlier.has_value());
  EXPECT_FALSE(config.congestion_rejection_factor.has_value());
  EXPECT_TRUE(config.estimate_noise_when_congested);
}

class FieldTrialsOverriddenJitterEstimatorTest : public JitterEstimatorTest {
 protected:
  FieldTrialsOverriddenJitterEstimatorTest()
      : JitterEstimatorTest(
            "WebRTC-JitterEstimatorConfig/"
            "avg_frame_size_median:true,"
            "max_frame_size_percentile:0.9,"
            "frame_size_window:30,"
            "num_stddev_delay_clamp:1.1,"
            "num_stddev_delay_outlier:2,"
            "num_stddev_size_outlier:3.1,"
            "congestion_rejection_factor:-1.55,"
            "estimate_noise_when_congested:false,"
            "nack_limit:2,"
            "nack_count_timeout:100ms/") {}
  ~FieldTrialsOverriddenJitterEstimatorTest() override {}
};

TEST_F(FieldTrialsOverriddenJitterEstimatorTest, FieldTrialsParsesCorrectly) {
  JitterEstimator::Config config = estimator_.GetConfigForTest();
  EXPECT_TRUE(config.avg_frame_size_median);
  EXPECT_EQ(*config.max_frame_size_percentile, 0.9);
  EXPECT_EQ(*config.frame_size_window, 30);
  EXPECT_EQ(*config.num_stddev_delay_clamp, 1.1);
  EXPECT_EQ(*config.num_stddev_delay_outlier, 2.0);
  EXPECT_EQ(*config.num_stddev_size_outlier, 3.1);
  EXPECT_EQ(*config.congestion_rejection_factor, -1.55);
  EXPECT_FALSE(config.estimate_noise_when_congested);
  EXPECT_EQ(*config.nack_limit, 2);
  EXPECT_EQ(*config.nack_count_timeout, TimeDelta::Millis(100));
}

TEST_F(FieldTrialsOverriddenJitterEstimatorTest,
       DelayOutlierIsRejectedAndMaintainsJitterEstimate) {
  ValueGenerator gen(10);

  // Steady state.
  Run(/*duration_s=*/60, /*framerate_fps=*/30, gen);
  TimeDelta steady_state_jitter = estimator_.GetEstimate();

  // A single outlier frame size...
  estimator_.UpdateEstimate(10 * gen.Delay(), gen.FrameSize());
  TimeDelta outlier_jitter = estimator_.GetEstimate();

  // ...does not change the estimate.
  EXPECT_EQ(outlier_jitter.ms(), steady_state_jitter.ms());
}

// The field trial is configured to be robust against the `(1 - 0.9) = 10%`
// largest frames over a window of length `30`.
TEST_F(FieldTrialsOverriddenJitterEstimatorTest,
       Four2xFrameSizesImpactJitterEstimate) {
  ValueGenerator gen(10);

  // Steady state.
  Run(/*duration_s=*/60, /*framerate_fps=*/30, gen);
  TimeDelta steady_state_jitter = estimator_.GetEstimate();

  // Three outlier frames do not impact the jitter estimate.
  for (int i = 0; i < 3; ++i) {
    estimator_.UpdateEstimate(gen.Delay(), 2 * gen.FrameSize());
  }
  TimeDelta outlier_jitter_3x = estimator_.GetEstimate();
  EXPECT_EQ(outlier_jitter_3x.ms(), steady_state_jitter.ms());

  // Four outlier frames do impact the jitter estimate.
  estimator_.UpdateEstimate(gen.Delay(), 2 * gen.FrameSize());
  TimeDelta outlier_jitter_4x = estimator_.GetEstimate();
  EXPECT_GT(outlier_jitter_4x.ms(), outlier_jitter_3x.ms());
}

// When so configured, congested frames are NOT used when calculating the
// noise variance, meaning that they will NOT impact the final jitter estimate.
TEST_F(FieldTrialsOverriddenJitterEstimatorTest,
       CongestedFrameDoesNotImpactJitterEstimate) {
  ValueGenerator gen(10);

  // Steady state.
  Run(/*duration_s=*/10, /*framerate_fps=*/30, gen);
  TimeDelta steady_state_jitter = estimator_.GetEstimate();

  // Congested frame...
  estimator_.UpdateEstimate(-10 * gen.Delay(), 0.1 * gen.FrameSize());
  TimeDelta outlier_jitter = estimator_.GetEstimate();

  // ...does not impact the estimate.
  EXPECT_EQ(outlier_jitter.ms(), steady_state_jitter.ms());
}

TEST_F(FieldTrialsOverriddenJitterEstimatorTest,
       NackedFramesIncreaseEstimateWithinTimeoutWindow) {
  ValueGenerator gen(10);
  constexpr TimeDelta kRtt = TimeDelta::Millis(100);
  const TimeDelta kNackCountTimeout =
      estimator_.GetConfigForTest().nack_count_timeout.value();
  estimator_.UpdateRtt(kRtt);

  // Ten perfect frames stabilize the estimate.
  for (int i = 0; i < 10; ++i) {
    fake_clock_.AdvanceTime(kInterArrivalTime);
    estimator_.UpdateEstimate(gen.Delay(), gen.FrameSize());
    gen.Advance();
  }
  EXPECT_EQ(estimator_.GetEstimate(), TimeDelta::Millis(11));

  // RTT is added to estimate after two NACKed frames.
  fake_clock_.AdvanceTime(kInterArrivalTime);
  estimator_.FrameNacked();
  estimator_.UpdateEstimate(gen.Delay() + kRtt, gen.FrameSize());
  gen.Advance();
  EXPECT_EQ(estimator_.GetEstimate(), TimeDelta::Millis(11));
  fake_clock_.AdvanceTime(kInterArrivalTime);
  estimator_.FrameNacked();
  estimator_.UpdateEstimate(gen.Delay(), gen.FrameSize());
  gen.Advance();
  EXPECT_EQ(estimator_.GetEstimate(), TimeDelta::Millis(11) + kRtt * kRttMult);

  // RTT is removed from estimate after timeout has passed with no NACKed
  // frames.
  fake_clock_.AdvanceTime(kNackCountTimeout);
  estimator_.UpdateEstimate(gen.Delay() - kRtt, gen.FrameSize());
  gen.Advance();
  EXPECT_EQ(estimator_.GetEstimate(), TimeDelta::Millis(11) + kRtt * kRttMult);

  fake_clock_.AdvanceTime(TimeDelta::Millis(1));
  estimator_.UpdateEstimate(gen.Delay(), gen.FrameSize());
  gen.Advance();
  EXPECT_EQ(estimator_.GetEstimate(), TimeDelta::Millis(11));
}

TEST_F(FieldTrialsOverriddenJitterEstimatorTest, AppliesRttMultiplierCap) {
  ValueGenerator gen(10);
  constexpr TimeDelta kRtt = kRttMultAddCap * 2;
  estimator_.UpdateRtt(kRtt);

  // Ten perfect frames stabilize the estimate.
  for (int i = 0; i < 10; ++i) {
    fake_clock_.AdvanceTime(kInterArrivalTime);
    estimator_.UpdateEstimate(gen.Delay(), gen.FrameSize());
    gen.Advance();
  }
  EXPECT_EQ(estimator_.GetEstimate(), TimeDelta::Millis(11));

  // Capped RTT should be added to estimate after two NACKed frames.
  fake_clock_.AdvanceTime(kInterArrivalTime);
  estimator_.FrameNacked();
  estimator_.UpdateEstimate(gen.Delay() + kRtt, gen.FrameSize());
  gen.Advance();
  EXPECT_EQ(estimator_.GetEstimate(), TimeDelta::Millis(11));
  fake_clock_.AdvanceTime(kInterArrivalTime);
  estimator_.FrameNacked();
  estimator_.UpdateEstimate(gen.Delay(), gen.FrameSize());
  gen.Advance();
  EXPECT_EQ(estimator_.GetEstimate(), TimeDelta::Millis(11) + kRttMultAddCap);
}

class MisconfiguredFieldTrialsJitterEstimatorTest : public JitterEstimatorTest {
 protected:
  MisconfiguredFieldTrialsJitterEstimatorTest()
      : JitterEstimatorTest(
            "WebRTC-JitterEstimatorConfig/"
            "max_frame_size_percentile:-0.9,"
            "frame_size_window:-1,"
            "num_stddev_delay_clamp:-1.9,"
            "num_stddev_delay_outlier:-2,"
            "num_stddev_size_outlier:-23.1,"
            "nack_limit:-1,"
            "nack_count_timeout:0s/") {}
  ~MisconfiguredFieldTrialsJitterEstimatorTest() override {}
};

TEST_F(MisconfiguredFieldTrialsJitterEstimatorTest, FieldTrialsAreValidated) {
  JitterEstimator::Config config = estimator_.GetConfigForTest();
  EXPECT_EQ(*config.max_frame_size_percentile, 0.0);
  EXPECT_EQ(*config.frame_size_window, 1);
  EXPECT_EQ(*config.num_stddev_delay_clamp, 0.0);
  EXPECT_EQ(*config.num_stddev_delay_outlier, 0.0);
  EXPECT_EQ(*config.num_stddev_size_outlier, 0.0);
  EXPECT_FALSE(config.nack_limit.has_value());
  EXPECT_FALSE(config.nack_count_timeout.has_value());
}

}  // namespace
}  // namespace webrtc
