/*
 *  Copyright (c) 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 "modules/remote_bitrate_estimator/aimd_rate_control.h"

#include "api/units/data_rate.h"
#include "api/units/time_delta.h"
#include "api/units/timestamp.h"
#include "test/explicit_key_value_config.h"
#include "test/gtest.h"

namespace webrtc {
namespace {

using ::webrtc::test::ExplicitKeyValueConfig;

constexpr Timestamp kInitialTime = Timestamp::Millis(123'456);

constexpr TimeDelta kMinBwePeriod = TimeDelta::Seconds(2);
constexpr TimeDelta kDefaultPeriod = TimeDelta::Seconds(3);
constexpr TimeDelta kMaxBwePeriod = TimeDelta::Seconds(50);

// After an overuse, we back off to 85% to the received bitrate.
constexpr double kFractionAfterOveruse = 0.85;

}  // namespace

TEST(AimdRateControlTest, MinNearMaxIncreaseRateOnLowBandwith) {
  AimdRateControl aimd_rate_control(ExplicitKeyValueConfig(""));
  aimd_rate_control.SetEstimate(DataRate::BitsPerSec(30'000), kInitialTime);
  EXPECT_EQ(aimd_rate_control.GetNearMaxIncreaseRateBpsPerSecond(), 4'000);
}

TEST(AimdRateControlTest, NearMaxIncreaseRateIs5kbpsOn90kbpsAnd200msRtt) {
  AimdRateControl aimd_rate_control(ExplicitKeyValueConfig(""));
  aimd_rate_control.SetEstimate(DataRate::BitsPerSec(90'000), kInitialTime);
  EXPECT_EQ(aimd_rate_control.GetNearMaxIncreaseRateBpsPerSecond(), 5'000);
}

TEST(AimdRateControlTest, NearMaxIncreaseRateIs5kbpsOn60kbpsAnd100msRtt) {
  AimdRateControl aimd_rate_control(ExplicitKeyValueConfig(""));
  aimd_rate_control.SetEstimate(DataRate::BitsPerSec(60'000), kInitialTime);
  aimd_rate_control.SetRtt(TimeDelta::Millis(100));
  EXPECT_EQ(aimd_rate_control.GetNearMaxIncreaseRateBpsPerSecond(), 5'000);
}

TEST(AimdRateControlTest, GetIncreaseRateAndBandwidthPeriod) {
  AimdRateControl aimd_rate_control(ExplicitKeyValueConfig(""));
  constexpr DataRate kBitrate = DataRate::BitsPerSec(300'000);
  aimd_rate_control.SetEstimate(kBitrate, kInitialTime);
  aimd_rate_control.Update({BandwidthUsage::kBwOverusing, kBitrate},
                           kInitialTime);
  EXPECT_NEAR(aimd_rate_control.GetNearMaxIncreaseRateBpsPerSecond(), 14'000,
              1'000);
  EXPECT_EQ(aimd_rate_control.GetExpectedBandwidthPeriod(), kDefaultPeriod);
}

TEST(AimdRateControlTest, BweLimitedByAckedBitrate) {
  AimdRateControl aimd_rate_control(ExplicitKeyValueConfig(""));
  constexpr DataRate kAckedBitrate = DataRate::BitsPerSec(10'000);
  Timestamp now = kInitialTime;
  aimd_rate_control.SetEstimate(kAckedBitrate, now);
  while (now - kInitialTime < TimeDelta::Seconds(20)) {
    aimd_rate_control.Update({BandwidthUsage::kBwNormal, kAckedBitrate}, now);
    now += TimeDelta::Millis(100);
  }
  ASSERT_TRUE(aimd_rate_control.ValidEstimate());
  EXPECT_EQ(aimd_rate_control.LatestEstimate(),
            1.5 * kAckedBitrate + DataRate::BitsPerSec(10'000));
}

TEST(AimdRateControlTest, BweNotLimitedByDecreasingAckedBitrate) {
  AimdRateControl aimd_rate_control(ExplicitKeyValueConfig(""));
  constexpr DataRate kAckedBitrate = DataRate::BitsPerSec(10'000);
  Timestamp now = kInitialTime;
  aimd_rate_control.SetEstimate(kAckedBitrate, now);
  while (now - kInitialTime < TimeDelta::Seconds(20)) {
    aimd_rate_control.Update({BandwidthUsage::kBwNormal, kAckedBitrate}, now);
    now += TimeDelta::Millis(100);
  }
  ASSERT_TRUE(aimd_rate_control.ValidEstimate());
  // If the acked bitrate decreases the BWE shouldn't be reduced to 1.5x
  // what's being acked, but also shouldn't get to increase more.
  DataRate prev_estimate = aimd_rate_control.LatestEstimate();
  aimd_rate_control.Update({BandwidthUsage::kBwNormal, kAckedBitrate / 2}, now);
  DataRate new_estimate = aimd_rate_control.LatestEstimate();
  EXPECT_EQ(new_estimate, prev_estimate);
  EXPECT_NEAR(new_estimate.bps(),
              (1.5 * kAckedBitrate + DataRate::BitsPerSec(10'000)).bps(),
              2'000);
}

TEST(AimdRateControlTest, DefaultPeriodUntilFirstOveruse) {
  AimdRateControl aimd_rate_control(ExplicitKeyValueConfig(""));
  aimd_rate_control.SetStartBitrate(DataRate::KilobitsPerSec(300));
  EXPECT_EQ(aimd_rate_control.GetExpectedBandwidthPeriod(), kDefaultPeriod);
  aimd_rate_control.Update(
      {BandwidthUsage::kBwOverusing, DataRate::KilobitsPerSec(280)},
      kInitialTime);
  EXPECT_NE(aimd_rate_control.GetExpectedBandwidthPeriod(), kDefaultPeriod);
}

TEST(AimdRateControlTest, ExpectedPeriodAfterTypicalDrop) {
  AimdRateControl aimd_rate_control(ExplicitKeyValueConfig(""));
  // The rate increase at 216 kbps should be 12 kbps. If we drop from
  // 216 + 4*12 = 264 kbps, it should take 4 seconds to recover. Since we
  // back off to 0.85*acked_rate-5kbps, the acked bitrate needs to be 260
  // kbps to end up at 216 kbps.
  constexpr DataRate kInitialBitrate = DataRate::BitsPerSec(264'000);
  constexpr DataRate kUpdatedBitrate = DataRate::BitsPerSec(216'000);
  const DataRate kAckedBitrate =
      (kUpdatedBitrate + DataRate::BitsPerSec(5'000)) / kFractionAfterOveruse;
  Timestamp now = kInitialTime;
  aimd_rate_control.SetEstimate(kInitialBitrate, now);
  now += TimeDelta::Millis(100);
  aimd_rate_control.Update({BandwidthUsage::kBwOverusing, kAckedBitrate}, now);
  EXPECT_EQ(aimd_rate_control.LatestEstimate(), kUpdatedBitrate);
  EXPECT_EQ(aimd_rate_control.GetNearMaxIncreaseRateBpsPerSecond(), 12'000);
  EXPECT_EQ(aimd_rate_control.GetExpectedBandwidthPeriod(),
            TimeDelta::Seconds(4));
}

TEST(AimdRateControlTest, BandwidthPeriodIsNotBelowMin) {
  AimdRateControl aimd_rate_control(ExplicitKeyValueConfig(""));
  constexpr DataRate kInitialBitrate = DataRate::BitsPerSec(10'000);
  Timestamp now = kInitialTime;
  aimd_rate_control.SetEstimate(kInitialBitrate, now);
  now += TimeDelta::Millis(100);
  // Make a small (1.5 kbps) bitrate drop to 8.5 kbps.
  aimd_rate_control.Update(
      {BandwidthUsage::kBwOverusing, kInitialBitrate - DataRate::BitsPerSec(1)},
      now);
  EXPECT_EQ(aimd_rate_control.GetExpectedBandwidthPeriod(), kMinBwePeriod);
}

TEST(AimdRateControlTest, BandwidthPeriodIsNotAboveMaxNoSmoothingExp) {
  AimdRateControl aimd_rate_control(ExplicitKeyValueConfig(""));
  constexpr DataRate kInitialBitrate = DataRate::BitsPerSec(10'010'000);
  Timestamp now = kInitialTime;
  aimd_rate_control.SetEstimate(kInitialBitrate, now);
  now += TimeDelta::Millis(100);
  // Make a large (10 Mbps) bitrate drop to 10 kbps.
  const DataRate kAckedBitrate =
      DataRate::BitsPerSec(10'000) / kFractionAfterOveruse;
  aimd_rate_control.Update({BandwidthUsage::kBwOverusing, kAckedBitrate}, now);
  EXPECT_EQ(aimd_rate_control.GetExpectedBandwidthPeriod(), kMaxBwePeriod);
}

TEST(AimdRateControlTest, SendingRateBoundedWhenThroughputNotEstimated) {
  AimdRateControl aimd_rate_control(ExplicitKeyValueConfig(""));
  constexpr DataRate kInitialBitrate = DataRate::BitsPerSec(123'000);
  Timestamp now = kInitialTime;
  aimd_rate_control.Update({BandwidthUsage::kBwNormal, kInitialBitrate}, now);
  // AimdRateControl sets the initial bit rate to what it receives after
  // five seconds has passed.
  // TODO(bugs.webrtc.org/9379): The comment in the AimdRateControl does not
  // match the constant.
  constexpr TimeDelta kInitializationTime = TimeDelta::Seconds(5);
  now += (kInitializationTime + TimeDelta::Millis(1));
  aimd_rate_control.Update({BandwidthUsage::kBwNormal, kInitialBitrate}, now);
  for (int i = 0; i < 100; ++i) {
    aimd_rate_control.Update({BandwidthUsage::kBwNormal, absl::nullopt}, now);
    now += TimeDelta::Millis(100);
  }
  EXPECT_LE(aimd_rate_control.LatestEstimate(),
            kInitialBitrate * 1.5 + DataRate::BitsPerSec(10'000));
}

TEST(AimdRateControlTest, EstimateDoesNotIncreaseInAlr) {
  // When alr is detected, the delay based estimator is not allowed to increase
  // bwe since there will be no feedback from the network if the new estimate
  // is correct.
  ExplicitKeyValueConfig field_trials(
      "WebRTC-DontIncreaseDelayBasedBweInAlr/Enabled/");
  AimdRateControl aimd_rate_control(field_trials, /*send_side=*/true);
  Timestamp now = kInitialTime;
  constexpr DataRate kInitialBitrate = DataRate::BitsPerSec(123'000);
  aimd_rate_control.SetEstimate(kInitialBitrate, now);
  aimd_rate_control.SetInApplicationLimitedRegion(true);
  aimd_rate_control.Update({BandwidthUsage::kBwNormal, kInitialBitrate}, now);
  ASSERT_EQ(aimd_rate_control.LatestEstimate(), kInitialBitrate);

  for (int i = 0; i < 100; ++i) {
    aimd_rate_control.Update({BandwidthUsage::kBwNormal, absl::nullopt}, now);
    now += TimeDelta::Millis(100);
  }
  EXPECT_EQ(aimd_rate_control.LatestEstimate(), kInitialBitrate);
}

TEST(AimdRateControlTest, SetEstimateIncreaseBweInAlr) {
  ExplicitKeyValueConfig field_trials(
      "WebRTC-DontIncreaseDelayBasedBweInAlr/Enabled/");
  AimdRateControl aimd_rate_control(field_trials, /*send_side=*/true);
  constexpr DataRate kInitialBitrate = DataRate::BitsPerSec(123'000);
  aimd_rate_control.SetEstimate(kInitialBitrate, kInitialTime);
  aimd_rate_control.SetInApplicationLimitedRegion(true);
  ASSERT_EQ(aimd_rate_control.LatestEstimate(), kInitialBitrate);
  aimd_rate_control.SetEstimate(2 * kInitialBitrate, kInitialTime);
  EXPECT_EQ(aimd_rate_control.LatestEstimate(), 2 * kInitialBitrate);
}

TEST(AimdRateControlTest, SetEstimateUpperLimitedByNetworkEstimate) {
  AimdRateControl aimd_rate_control(ExplicitKeyValueConfig(""),
                                    /*send_side=*/true);
  aimd_rate_control.SetEstimate(DataRate::BitsPerSec(300'000), kInitialTime);
  NetworkStateEstimate network_estimate;
  network_estimate.link_capacity_upper = DataRate::BitsPerSec(400'000);
  aimd_rate_control.SetNetworkStateEstimate(network_estimate);
  aimd_rate_control.SetEstimate(DataRate::BitsPerSec(500'000), kInitialTime);
  EXPECT_EQ(aimd_rate_control.LatestEstimate(),
            network_estimate.link_capacity_upper);
}

TEST(AimdRateControlTest,
     SetEstimateDefaultUpperLimitedByCurrentBitrateIfNetworkEstimateIsLow) {
  AimdRateControl aimd_rate_control(ExplicitKeyValueConfig(""),
                                    /*send_side=*/true);
  aimd_rate_control.SetEstimate(DataRate::BitsPerSec(500'000), kInitialTime);
  ASSERT_EQ(aimd_rate_control.LatestEstimate(), DataRate::BitsPerSec(500'000));

  NetworkStateEstimate network_estimate;
  network_estimate.link_capacity_upper = DataRate::BitsPerSec(300'000);
  aimd_rate_control.SetNetworkStateEstimate(network_estimate);
  aimd_rate_control.SetEstimate(DataRate::BitsPerSec(700'000), kInitialTime);
  EXPECT_EQ(aimd_rate_control.LatestEstimate(), DataRate::BitsPerSec(500'000));
}

TEST(AimdRateControlTest,
     SetEstimateNotUpperLimitedByCurrentBitrateIfNetworkEstimateIsLowIf) {
  AimdRateControl aimd_rate_control(
      ExplicitKeyValueConfig(
          "WebRTC-Bwe-EstimateBoundedIncrease/c_upper:false/"),
      /*send_side=*/true);

  aimd_rate_control.SetEstimate(DataRate::BitsPerSec(500'000), kInitialTime);
  ASSERT_EQ(aimd_rate_control.LatestEstimate(), DataRate::BitsPerSec(500'000));

  NetworkStateEstimate network_estimate;
  network_estimate.link_capacity_upper = DataRate::BitsPerSec(300'000);
  aimd_rate_control.SetNetworkStateEstimate(network_estimate);
  aimd_rate_control.SetEstimate(DataRate::BitsPerSec(700'000), kInitialTime);
  EXPECT_EQ(aimd_rate_control.LatestEstimate(), DataRate::BitsPerSec(300'000));
}

TEST(AimdRateControlTest, SetEstimateLowerLimitedByNetworkEstimate) {
  AimdRateControl aimd_rate_control(ExplicitKeyValueConfig(""),
                                    /*send_side=*/true);
  NetworkStateEstimate network_estimate;
  network_estimate.link_capacity_lower = DataRate::BitsPerSec(400'000);
  aimd_rate_control.SetNetworkStateEstimate(network_estimate);
  aimd_rate_control.SetEstimate(DataRate::BitsPerSec(100'000), kInitialTime);
  // 0.85 is default backoff factor. (`beta_`)
  EXPECT_EQ(aimd_rate_control.LatestEstimate(),
            network_estimate.link_capacity_lower * 0.85);
}

TEST(AimdRateControlTest,
     SetEstimateIgnoredIfLowerThanNetworkEstimateAndCurrent) {
  AimdRateControl aimd_rate_control(ExplicitKeyValueConfig(""),
                                    /*send_side=*/true);
  aimd_rate_control.SetEstimate(DataRate::KilobitsPerSec(200), kInitialTime);
  ASSERT_EQ(aimd_rate_control.LatestEstimate().kbps(), 200);
  NetworkStateEstimate network_estimate;
  network_estimate.link_capacity_lower = DataRate::KilobitsPerSec(400);
  aimd_rate_control.SetNetworkStateEstimate(network_estimate);
  // Ignore the next SetEstimate, since the estimate is lower than 85% of
  // the network estimate.
  aimd_rate_control.SetEstimate(DataRate::KilobitsPerSec(100), kInitialTime);
  EXPECT_EQ(aimd_rate_control.LatestEstimate().kbps(), 200);
}

TEST(AimdRateControlTest, EstimateIncreaseWhileNotInAlr) {
  // Allow the estimate to increase as long as alr is not detected to ensure
  // tha BWE can not get stuck at a certain bitrate.
  ExplicitKeyValueConfig field_trials(
      "WebRTC-DontIncreaseDelayBasedBweInAlr/Enabled/");
  AimdRateControl aimd_rate_control(field_trials, /*send_side=*/true);
  Timestamp now = kInitialTime;
  constexpr DataRate kInitialBitrate = DataRate::BitsPerSec(123'000);
  aimd_rate_control.SetEstimate(kInitialBitrate, now);
  aimd_rate_control.SetInApplicationLimitedRegion(false);
  aimd_rate_control.Update({BandwidthUsage::kBwNormal, kInitialBitrate}, now);
  for (int i = 0; i < 100; ++i) {
    aimd_rate_control.Update({BandwidthUsage::kBwNormal, absl::nullopt}, now);
    now += TimeDelta::Millis(100);
  }
  EXPECT_GT(aimd_rate_control.LatestEstimate(), kInitialBitrate);
}

TEST(AimdRateControlTest, EstimateNotLimitedByNetworkEstimateIfDisabled) {
  ExplicitKeyValueConfig field_trials(
      "WebRTC-Bwe-EstimateBoundedIncrease/Disabled/");
  AimdRateControl aimd_rate_control(field_trials, /*send_side=*/true);
  Timestamp now = kInitialTime;
  constexpr DataRate kInitialBitrate = DataRate::BitsPerSec(123'000);
  aimd_rate_control.SetEstimate(kInitialBitrate, now);
  aimd_rate_control.SetInApplicationLimitedRegion(false);
  NetworkStateEstimate network_estimate;
  network_estimate.link_capacity_upper = DataRate::KilobitsPerSec(150);
  aimd_rate_control.SetNetworkStateEstimate(network_estimate);

  for (int i = 0; i < 100; ++i) {
    aimd_rate_control.Update({BandwidthUsage::kBwNormal, absl::nullopt}, now);
    now += TimeDelta::Millis(100);
  }
  EXPECT_GT(aimd_rate_control.LatestEstimate(),
            network_estimate.link_capacity_upper);
}

}  // namespace webrtc
