/*  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 "webrtc/modules/video_coding/jitter_estimator.h"

#include "testing/gtest/include/gtest/gtest.h"
#include "webrtc/system_wrappers/include/clock.h"

namespace webrtc {

class TestEstimator : public VCMJitterEstimator {
 public:
  explicit TestEstimator(bool exp_enabled)
      : VCMJitterEstimator(&fake_clock_, 0, 0),
        fake_clock_(0),
        exp_enabled_(exp_enabled) {}

  virtual bool LowRateExperimentEnabled() { return exp_enabled_; }

  void AdvanceClock(int64_t microseconds) {
    fake_clock_.AdvanceTimeMicroseconds(microseconds);
  }

 private:
  SimulatedClock fake_clock_;
  const bool exp_enabled_;
};

class TestVCMJitterEstimator : public ::testing::Test {
 protected:
  TestVCMJitterEstimator()
      : regular_estimator_(false), low_rate_estimator_(true) {}

  virtual void SetUp() { regular_estimator_.Reset(); }

  TestEstimator regular_estimator_;
  TestEstimator low_rate_estimator_;
};

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

  int64_t Delay() { return ((counter_ % 11) - 5) * amplitude_; }

  uint32_t FrameSize() { return 1000 + Delay(); }

  void Advance() { ++counter_; }

 private:
  const int32_t amplitude_;
  int64_t counter_;
};

// 5 fps, disable jitter delay altogether.
TEST_F(TestVCMJitterEstimator, TestLowRate) {
  ValueGenerator gen(10);
  uint64_t time_delta = 1000000 / 5;
  for (int i = 0; i < 60; ++i) {
    regular_estimator_.UpdateEstimate(gen.Delay(), gen.FrameSize());
    regular_estimator_.AdvanceClock(time_delta);
    low_rate_estimator_.UpdateEstimate(gen.Delay(), gen.FrameSize());
    low_rate_estimator_.AdvanceClock(time_delta);
    EXPECT_GT(regular_estimator_.GetJitterEstimate(0), 0);
    if (i > 2)
      EXPECT_EQ(low_rate_estimator_.GetJitterEstimate(0), 0);
    gen.Advance();
  }
}

// 8 fps, steady state estimate should be in interpolated interval between 0
// and value of previous method.
TEST_F(TestVCMJitterEstimator, TestMidRate) {
  ValueGenerator gen(10);
  uint64_t time_delta = 1000000 / 8;
  for (int i = 0; i < 60; ++i) {
    regular_estimator_.UpdateEstimate(gen.Delay(), gen.FrameSize());
    regular_estimator_.AdvanceClock(time_delta);
    low_rate_estimator_.UpdateEstimate(gen.Delay(), gen.FrameSize());
    low_rate_estimator_.AdvanceClock(time_delta);
    EXPECT_GT(regular_estimator_.GetJitterEstimate(0), 0);
    EXPECT_GT(low_rate_estimator_.GetJitterEstimate(0), 0);
    EXPECT_GE(regular_estimator_.GetJitterEstimate(0),
              low_rate_estimator_.GetJitterEstimate(0));
    gen.Advance();
  }
}

// 30 fps, steady state estimate should be same as previous method.
TEST_F(TestVCMJitterEstimator, TestHighRate) {
  ValueGenerator gen(10);
  uint64_t time_delta = 1000000 / 30;
  for (int i = 0; i < 60; ++i) {
    regular_estimator_.UpdateEstimate(gen.Delay(), gen.FrameSize());
    regular_estimator_.AdvanceClock(time_delta);
    low_rate_estimator_.UpdateEstimate(gen.Delay(), gen.FrameSize());
    low_rate_estimator_.AdvanceClock(time_delta);
    EXPECT_EQ(regular_estimator_.GetJitterEstimate(0),
              low_rate_estimator_.GetJitterEstimate(0));
    gen.Advance();
  }
}

// 10 fps, high jitter then low jitter. Low rate estimator should converge
// faster to low noise estimate.
TEST_F(TestVCMJitterEstimator, TestConvergence) {
  // Reach a steady state with high noise.
  ValueGenerator gen(50);
  uint64_t time_delta = 1000000 / 10;
  for (int i = 0; i < 100; ++i) {
    regular_estimator_.UpdateEstimate(gen.Delay(), gen.FrameSize());
    regular_estimator_.AdvanceClock(time_delta * 2);
    low_rate_estimator_.UpdateEstimate(gen.Delay(), gen.FrameSize());
    low_rate_estimator_.AdvanceClock(time_delta * 2);
    gen.Advance();
  }

  int threshold = regular_estimator_.GetJitterEstimate(0) / 2;

  // New generator with zero noise.
  ValueGenerator low_gen(0);
  int regular_iterations = 0;
  int low_rate_iterations = 0;
  for (int i = 0; i < 500; ++i) {
    if (regular_iterations == 0) {
      regular_estimator_.UpdateEstimate(low_gen.Delay(), low_gen.FrameSize());
      regular_estimator_.AdvanceClock(time_delta);
      if (regular_estimator_.GetJitterEstimate(0) < threshold) {
        regular_iterations = i;
      }
    }

    if (low_rate_iterations == 0) {
      low_rate_estimator_.UpdateEstimate(low_gen.Delay(), low_gen.FrameSize());
      low_rate_estimator_.AdvanceClock(time_delta);
      if (low_rate_estimator_.GetJitterEstimate(0) < threshold) {
        low_rate_iterations = i;
      }
    }

    if (regular_iterations != 0 && low_rate_iterations != 0) {
      break;
    }

    gen.Advance();
  }

  EXPECT_NE(regular_iterations, 0);
  EXPECT_NE(low_rate_iterations, 0);
  EXPECT_LE(low_rate_iterations, regular_iterations);
}
}
