/*
 *  Copyright 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 "common_video/include/bitrate_adjuster.h"

#include "api/units/time_delta.h"
#include "rtc_base/fake_clock.h"
#include "test/gtest.h"

namespace webrtc {

class BitrateAdjusterTest : public ::testing::Test {
 public:
  BitrateAdjusterTest()
      : adjuster_(kMinAdjustedBitratePct, kMaxAdjustedBitratePct) {}

  // Simulate an output bitrate for one update cycle of BitrateAdjuster.
  void SimulateBitrateBps(uint32_t bitrate_bps) {
    const uint32_t update_interval_ms =
        BitrateAdjuster::kBitrateUpdateIntervalMs;
    const uint32_t update_frame_interval =
        BitrateAdjuster::kBitrateUpdateFrameInterval;
    // Round up frame interval so we get one cycle passes.
    const uint32_t frame_interval_ms =
        (update_interval_ms + update_frame_interval - 1) /
        update_frame_interval;
    const size_t frame_size_bytes =
        (bitrate_bps * frame_interval_ms) / (8 * 1000);
    for (size_t i = 0; i < update_frame_interval; ++i) {
      clock_.AdvanceTime(webrtc::TimeDelta::ms(frame_interval_ms));
      adjuster_.Update(frame_size_bytes);
    }
  }

  uint32_t GetTargetBitrateBpsPct(float pct) {
    return pct * adjuster_.GetTargetBitrateBps();
  }

  void VerifyAdjustment() {
    // The adjusted bitrate should be between the estimated bitrate and the
    // target bitrate within clamp.
    uint32_t target_bitrate_bps = adjuster_.GetTargetBitrateBps();
    uint32_t adjusted_bitrate_bps = adjuster_.GetAdjustedBitrateBps();
    uint32_t estimated_bitrate_bps =
        adjuster_.GetEstimatedBitrateBps().value_or(target_bitrate_bps);
    uint32_t adjusted_lower_bound_bps =
        GetTargetBitrateBpsPct(kMinAdjustedBitratePct);
    uint32_t adjusted_upper_bound_bps =
        GetTargetBitrateBpsPct(kMaxAdjustedBitratePct);
    EXPECT_LE(adjusted_bitrate_bps, adjusted_upper_bound_bps);
    EXPECT_GE(adjusted_bitrate_bps, adjusted_lower_bound_bps);
    if (estimated_bitrate_bps > target_bitrate_bps) {
      EXPECT_LT(adjusted_bitrate_bps, target_bitrate_bps);
    }
  }

 protected:
  static const float kMinAdjustedBitratePct;
  static const float kMaxAdjustedBitratePct;
  rtc::ScopedFakeClock clock_;
  BitrateAdjuster adjuster_;
};

const float BitrateAdjusterTest::kMinAdjustedBitratePct = .5f;
const float BitrateAdjusterTest::kMaxAdjustedBitratePct = .95f;

TEST_F(BitrateAdjusterTest, VaryingBitrates) {
  const uint32_t target_bitrate_bps = 640000;
  adjuster_.SetTargetBitrateBps(target_bitrate_bps);

  // Grossly overshoot for a little while. Adjusted bitrate should decrease.
  uint32_t actual_bitrate_bps = 2 * target_bitrate_bps;
  uint32_t last_adjusted_bitrate_bps = 0;
  uint32_t adjusted_bitrate_bps = 0;

  SimulateBitrateBps(actual_bitrate_bps);
  VerifyAdjustment();
  last_adjusted_bitrate_bps = adjuster_.GetAdjustedBitrateBps();

  SimulateBitrateBps(actual_bitrate_bps);
  VerifyAdjustment();
  adjusted_bitrate_bps = adjuster_.GetAdjustedBitrateBps();
  EXPECT_LE(adjusted_bitrate_bps, last_adjusted_bitrate_bps);
  last_adjusted_bitrate_bps = adjusted_bitrate_bps;
  // After two cycles we should've stabilized and hit the lower bound.
  EXPECT_EQ(GetTargetBitrateBpsPct(kMinAdjustedBitratePct),
            adjusted_bitrate_bps);

  // Simulate encoder settling down. Adjusted bitrate should increase.
  SimulateBitrateBps(target_bitrate_bps);
  adjusted_bitrate_bps = adjuster_.GetAdjustedBitrateBps();
  VerifyAdjustment();
  EXPECT_GT(adjusted_bitrate_bps, last_adjusted_bitrate_bps);
  last_adjusted_bitrate_bps = adjusted_bitrate_bps;

  SimulateBitrateBps(target_bitrate_bps);
  adjusted_bitrate_bps = adjuster_.GetAdjustedBitrateBps();
  VerifyAdjustment();
  EXPECT_GT(adjusted_bitrate_bps, last_adjusted_bitrate_bps);
  last_adjusted_bitrate_bps = adjusted_bitrate_bps;
  // After two cycles we should've stabilized and hit the upper bound.
  EXPECT_EQ(GetTargetBitrateBpsPct(kMaxAdjustedBitratePct),
            adjusted_bitrate_bps);
}

// Tests that large changes in target bitrate will result in immediate change
// in adjusted bitrate.
TEST_F(BitrateAdjusterTest, LargeTargetDelta) {
  uint32_t target_bitrate_bps = 640000;
  adjuster_.SetTargetBitrateBps(target_bitrate_bps);
  EXPECT_EQ(target_bitrate_bps, adjuster_.GetAdjustedBitrateBps());

  float delta_pct = BitrateAdjuster::kBitrateTolerancePct * 2;

  target_bitrate_bps = (1 + delta_pct) * target_bitrate_bps;
  adjuster_.SetTargetBitrateBps(target_bitrate_bps);
  EXPECT_EQ(target_bitrate_bps, adjuster_.GetAdjustedBitrateBps());

  target_bitrate_bps = (1 - delta_pct) * target_bitrate_bps;
  adjuster_.SetTargetBitrateBps(target_bitrate_bps);
  EXPECT_EQ(target_bitrate_bps, adjuster_.GetAdjustedBitrateBps());
}

// Tests that small changes in target bitrate within tolerance will not affect
// adjusted bitrate immediately.
TEST_F(BitrateAdjusterTest, SmallTargetDelta) {
  const uint32_t initial_target_bitrate_bps = 640000;
  uint32_t target_bitrate_bps = initial_target_bitrate_bps;
  adjuster_.SetTargetBitrateBps(target_bitrate_bps);
  EXPECT_EQ(initial_target_bitrate_bps, adjuster_.GetAdjustedBitrateBps());

  float delta_pct = BitrateAdjuster::kBitrateTolerancePct / 2;

  target_bitrate_bps = (1 + delta_pct) * target_bitrate_bps;
  adjuster_.SetTargetBitrateBps(target_bitrate_bps);
  EXPECT_EQ(initial_target_bitrate_bps, adjuster_.GetAdjustedBitrateBps());

  target_bitrate_bps = (1 - delta_pct) * target_bitrate_bps;
  adjuster_.SetTargetBitrateBps(target_bitrate_bps);
  EXPECT_EQ(initial_target_bitrate_bps, adjuster_.GetAdjustedBitrateBps());
}

TEST_F(BitrateAdjusterTest, SmallTargetDeltaOverflow) {
  const uint32_t initial_target_bitrate_bps = 640000;
  uint32_t target_bitrate_bps = initial_target_bitrate_bps;
  adjuster_.SetTargetBitrateBps(target_bitrate_bps);
  EXPECT_EQ(initial_target_bitrate_bps, adjuster_.GetAdjustedBitrateBps());

  float delta_pct = BitrateAdjuster::kBitrateTolerancePct / 2;

  target_bitrate_bps = (1 + delta_pct) * target_bitrate_bps;
  adjuster_.SetTargetBitrateBps(target_bitrate_bps);
  EXPECT_EQ(initial_target_bitrate_bps, adjuster_.GetAdjustedBitrateBps());

  // 1.05 * 1.05 is 1.1 which is greater than tolerance for the initial target
  // bitrate. Since we didn't advance the clock the adjuster never updated.
  target_bitrate_bps = (1 + delta_pct) * target_bitrate_bps;
  adjuster_.SetTargetBitrateBps(target_bitrate_bps);
  EXPECT_EQ(target_bitrate_bps, adjuster_.GetAdjustedBitrateBps());
}

}  // namespace webrtc
