/*
 *  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/congestion_controller/goog_cc/probe_controller.h"

#include <memory>

#include "api/transport/field_trial_based_config.h"
#include "api/transport/network_types.h"
#include "api/units/data_rate.h"
#include "api/units/timestamp.h"
#include "logging/rtc_event_log/mock/mock_rtc_event_log.h"
#include "rtc_base/logging.h"
#include "system_wrappers/include/clock.h"
#include "test/field_trial.h"
#include "test/gmock.h"
#include "test/gtest.h"

using ::testing::_;
using ::testing::AtLeast;
using ::testing::Field;
using ::testing::Matcher;
using ::testing::NiceMock;
using ::testing::Return;

namespace webrtc {
namespace test {

namespace {

constexpr int kMinBitrateBps = 100;
constexpr int kStartBitrateBps = 300;
constexpr int kMaxBitrateBps = 10000;

constexpr int kExponentialProbingTimeoutMs = 5000;

constexpr int kAlrProbeInterval = 5000;
constexpr int kAlrEndedTimeoutMs = 3000;
constexpr int kBitrateDropTimeoutMs = 5000;
}  // namespace

class ProbeControllerTest : public ::testing::Test {
 protected:
  ProbeControllerTest() : clock_(100000000L) {
    probe_controller_.reset(
        new ProbeController(&field_trial_config_, &mock_rtc_event_log));
  }
  ~ProbeControllerTest() override {}

  std::vector<ProbeClusterConfig> SetNetworkAvailable(bool available) {
    NetworkAvailability msg;
    msg.at_time = Timestamp::ms(NowMs());
    msg.network_available = available;
    return probe_controller_->OnNetworkAvailability(msg);
  }

  int64_t NowMs() { return clock_.TimeInMilliseconds(); }

  FieldTrialBasedConfig field_trial_config_;
  SimulatedClock clock_;
  NiceMock<MockRtcEventLog> mock_rtc_event_log;
  std::unique_ptr<ProbeController> probe_controller_;
};

TEST_F(ProbeControllerTest, InitiatesProbingAtStart) {
  auto probes = probe_controller_->SetBitrates(kMinBitrateBps, kStartBitrateBps,
                                               kMaxBitrateBps, NowMs());
  EXPECT_GE(probes.size(), 2u);
}

TEST_F(ProbeControllerTest, ProbeOnlyWhenNetworkIsUp) {
  SetNetworkAvailable(false);
  auto probes = probe_controller_->SetBitrates(kMinBitrateBps, kStartBitrateBps,
                                               kMaxBitrateBps, NowMs());
  EXPECT_EQ(probes.size(), 0u);
  probes = SetNetworkAvailable(true);
  EXPECT_GE(probes.size(), 2u);
}

TEST_F(ProbeControllerTest, InitiatesProbingOnMaxBitrateIncrease) {
  auto probes = probe_controller_->SetBitrates(kMinBitrateBps, kStartBitrateBps,
                                               kMaxBitrateBps, NowMs());
  // Long enough to time out exponential probing.
  clock_.AdvanceTimeMilliseconds(kExponentialProbingTimeoutMs);
  probes = probe_controller_->SetEstimatedBitrate(kStartBitrateBps, NowMs());
  probes = probe_controller_->Process(NowMs());
  probes = probe_controller_->SetBitrates(kMinBitrateBps, kStartBitrateBps,
                                          kMaxBitrateBps + 100, NowMs());
  EXPECT_EQ(probes.size(), 1u);
  EXPECT_EQ(probes[0].target_data_rate.bps(), kMaxBitrateBps + 100);
}

TEST_F(ProbeControllerTest, ProbesOnMaxBitrateIncreaseOnlyWhenInAlr) {
  test::ScopedFieldTrials trials("WebRTC-BweAllocProbingOnlyInAlr/Enabled/");
  probe_controller_.reset(
      new ProbeController(&field_trial_config_, &mock_rtc_event_log));
  auto probes = probe_controller_->SetBitrates(kMinBitrateBps, kStartBitrateBps,
                                               kMaxBitrateBps, NowMs());
  probes = probe_controller_->SetEstimatedBitrate(kMaxBitrateBps - 1, NowMs());

  // Wait long enough to time out exponential probing.
  clock_.AdvanceTimeMilliseconds(kExponentialProbingTimeoutMs);
  probes = probe_controller_->Process(NowMs());
  EXPECT_EQ(probes.size(), 0u);

  // Probe when in alr.
  probe_controller_->SetAlrStartTimeMs(clock_.TimeInMilliseconds());
  probes = probe_controller_->OnMaxTotalAllocatedBitrate(kMaxBitrateBps + 1,
                                                         NowMs());
  EXPECT_EQ(probes.size(), 2u);

  // Do not probe when not in alr.
  probe_controller_->SetAlrStartTimeMs(absl::nullopt);
  probes = probe_controller_->OnMaxTotalAllocatedBitrate(kMaxBitrateBps + 2,
                                                         NowMs());
  EXPECT_TRUE(probes.empty());
}

TEST_F(ProbeControllerTest, InitiatesProbingOnMaxBitrateIncreaseAtMaxBitrate) {
  auto probes = probe_controller_->SetBitrates(kMinBitrateBps, kStartBitrateBps,
                                               kMaxBitrateBps, NowMs());
  // Long enough to time out exponential probing.
  clock_.AdvanceTimeMilliseconds(kExponentialProbingTimeoutMs);
  probes = probe_controller_->SetEstimatedBitrate(kStartBitrateBps, NowMs());
  probes = probe_controller_->Process(NowMs());
  probes = probe_controller_->SetEstimatedBitrate(kMaxBitrateBps, NowMs());
  probes = probe_controller_->SetBitrates(kMinBitrateBps, kStartBitrateBps,
                                          kMaxBitrateBps + 100, NowMs());
  EXPECT_EQ(probes.size(), 1u);
  EXPECT_EQ(probes[0].target_data_rate.bps(), kMaxBitrateBps + 100);
}

TEST_F(ProbeControllerTest, TestExponentialProbing) {
  auto probes = probe_controller_->SetBitrates(kMinBitrateBps, kStartBitrateBps,
                                               kMaxBitrateBps, NowMs());

  // Repeated probe should only be sent when estimated bitrate climbs above
  // 0.7 * 6 * kStartBitrateBps = 1260.
  probes = probe_controller_->SetEstimatedBitrate(1000, NowMs());
  EXPECT_EQ(probes.size(), 0u);

  probes = probe_controller_->SetEstimatedBitrate(1800, NowMs());
  EXPECT_EQ(probes.size(), 1u);
  EXPECT_EQ(probes[0].target_data_rate.bps(), 2 * 1800);
}

TEST_F(ProbeControllerTest, TestExponentialProbingTimeout) {
  auto probes = probe_controller_->SetBitrates(kMinBitrateBps, kStartBitrateBps,
                                               kMaxBitrateBps, NowMs());
  // Advance far enough to cause a time out in waiting for probing result.
  clock_.AdvanceTimeMilliseconds(kExponentialProbingTimeoutMs);
  probes = probe_controller_->Process(NowMs());

  probes = probe_controller_->SetEstimatedBitrate(1800, NowMs());
  EXPECT_EQ(probes.size(), 0u);
}

TEST_F(ProbeControllerTest, RequestProbeInAlr) {
  auto probes = probe_controller_->SetBitrates(kMinBitrateBps, kStartBitrateBps,
                                               kMaxBitrateBps, NowMs());
  EXPECT_GE(probes.size(), 2u);
  probes = probe_controller_->SetEstimatedBitrate(500, NowMs());

  probe_controller_->SetAlrStartTimeMs(clock_.TimeInMilliseconds());
  clock_.AdvanceTimeMilliseconds(kAlrProbeInterval + 1);
  probes = probe_controller_->Process(NowMs());
  probes = probe_controller_->SetEstimatedBitrate(250, NowMs());
  probes = probe_controller_->RequestProbe(NowMs());

  EXPECT_EQ(probes.size(), 1u);
  EXPECT_EQ(probes[0].target_data_rate.bps(), 0.85 * 500);
}

TEST_F(ProbeControllerTest, RequestProbeWhenAlrEndedRecently) {
  auto probes = probe_controller_->SetBitrates(kMinBitrateBps, kStartBitrateBps,
                                               kMaxBitrateBps, NowMs());
  EXPECT_EQ(probes.size(), 2u);
  probes = probe_controller_->SetEstimatedBitrate(500, NowMs());

  probe_controller_->SetAlrStartTimeMs(absl::nullopt);
  clock_.AdvanceTimeMilliseconds(kAlrProbeInterval + 1);
  probes = probe_controller_->Process(NowMs());
  probes = probe_controller_->SetEstimatedBitrate(250, NowMs());
  probe_controller_->SetAlrEndedTimeMs(clock_.TimeInMilliseconds());
  clock_.AdvanceTimeMilliseconds(kAlrEndedTimeoutMs - 1);
  probes = probe_controller_->RequestProbe(NowMs());

  EXPECT_EQ(probes.size(), 1u);
  EXPECT_EQ(probes[0].target_data_rate.bps(), 0.85 * 500);
}

TEST_F(ProbeControllerTest, RequestProbeWhenAlrNotEndedRecently) {
  auto probes = probe_controller_->SetBitrates(kMinBitrateBps, kStartBitrateBps,
                                               kMaxBitrateBps, NowMs());
  EXPECT_EQ(probes.size(), 2u);
  probes = probe_controller_->SetEstimatedBitrate(500, NowMs());

  probe_controller_->SetAlrStartTimeMs(absl::nullopt);
  clock_.AdvanceTimeMilliseconds(kAlrProbeInterval + 1);
  probes = probe_controller_->Process(NowMs());
  probes = probe_controller_->SetEstimatedBitrate(250, NowMs());
  probe_controller_->SetAlrEndedTimeMs(clock_.TimeInMilliseconds());
  clock_.AdvanceTimeMilliseconds(kAlrEndedTimeoutMs + 1);
  probes = probe_controller_->RequestProbe(NowMs());
  EXPECT_EQ(probes.size(), 0u);
}

TEST_F(ProbeControllerTest, RequestProbeWhenBweDropNotRecent) {
  auto probes = probe_controller_->SetBitrates(kMinBitrateBps, kStartBitrateBps,
                                               kMaxBitrateBps, NowMs());
  EXPECT_EQ(probes.size(), 2u);
  probes = probe_controller_->SetEstimatedBitrate(500, NowMs());

  probe_controller_->SetAlrStartTimeMs(clock_.TimeInMilliseconds());
  clock_.AdvanceTimeMilliseconds(kAlrProbeInterval + 1);
  probes = probe_controller_->Process(NowMs());
  probes = probe_controller_->SetEstimatedBitrate(250, NowMs());
  clock_.AdvanceTimeMilliseconds(kBitrateDropTimeoutMs + 1);
  probes = probe_controller_->RequestProbe(NowMs());
  EXPECT_EQ(probes.size(), 0u);
}

TEST_F(ProbeControllerTest, PeriodicProbing) {
  probe_controller_->EnablePeriodicAlrProbing(true);
  auto probes = probe_controller_->SetBitrates(kMinBitrateBps, kStartBitrateBps,
                                               kMaxBitrateBps, NowMs());
  EXPECT_EQ(probes.size(), 2u);
  probes = probe_controller_->SetEstimatedBitrate(500, NowMs());

  int64_t start_time = clock_.TimeInMilliseconds();

  // Expect the controller to send a new probe after 5s has passed.
  probe_controller_->SetAlrStartTimeMs(start_time);
  clock_.AdvanceTimeMilliseconds(5000);
  probes = probe_controller_->Process(NowMs());
  EXPECT_EQ(probes.size(), 1u);
  EXPECT_EQ(probes[0].target_data_rate.bps(), 1000);

  probes = probe_controller_->SetEstimatedBitrate(500, NowMs());

  // The following probe should be sent at 10s into ALR.
  probe_controller_->SetAlrStartTimeMs(start_time);
  clock_.AdvanceTimeMilliseconds(4000);
  probes = probe_controller_->Process(NowMs());
  probes = probe_controller_->SetEstimatedBitrate(500, NowMs());
  EXPECT_EQ(probes.size(), 0u);

  probe_controller_->SetAlrStartTimeMs(start_time);
  clock_.AdvanceTimeMilliseconds(1000);
  probes = probe_controller_->Process(NowMs());
  EXPECT_EQ(probes.size(), 1u);
  probes = probe_controller_->SetEstimatedBitrate(500, NowMs());
  EXPECT_EQ(probes.size(), 0u);
}

TEST_F(ProbeControllerTest, PeriodicProbingAfterReset) {
  probe_controller_.reset(
      new ProbeController(&field_trial_config_, &mock_rtc_event_log));
  int64_t alr_start_time = clock_.TimeInMilliseconds();

  probe_controller_->SetAlrStartTimeMs(alr_start_time);
  probe_controller_->EnablePeriodicAlrProbing(true);
  auto probes = probe_controller_->SetBitrates(kMinBitrateBps, kStartBitrateBps,
                                               kMaxBitrateBps, NowMs());
  probe_controller_->Reset(NowMs());

  clock_.AdvanceTimeMilliseconds(10000);
  probes = probe_controller_->Process(NowMs());
  // Since bitrates are not yet set, no probe is sent event though we are in ALR
  // mode.
  EXPECT_EQ(probes.size(), 0u);

  probes = probe_controller_->SetBitrates(kMinBitrateBps, kStartBitrateBps,
                                          kMaxBitrateBps, NowMs());
  EXPECT_EQ(probes.size(), 2u);

  // Make sure we use |kStartBitrateBps| as the estimated bitrate
  // until SetEstimatedBitrate is called with an updated estimate.
  clock_.AdvanceTimeMilliseconds(10000);
  probes = probe_controller_->Process(NowMs());
  EXPECT_EQ(probes.size(), 1u);
  EXPECT_EQ(probes[0].target_data_rate.bps(), kStartBitrateBps * 2);
}

TEST_F(ProbeControllerTest, TestExponentialProbingOverflow) {
  const int64_t kMbpsMultiplier = 1000000;
  auto probes = probe_controller_->SetBitrates(
      kMinBitrateBps, 10 * kMbpsMultiplier, 100 * kMbpsMultiplier, NowMs());
  // Verify that probe bitrate is capped at the specified max bitrate.
  probes =
      probe_controller_->SetEstimatedBitrate(60 * kMbpsMultiplier, NowMs());
  EXPECT_EQ(probes.size(), 1u);
  EXPECT_EQ(probes[0].target_data_rate.bps(), 100 * kMbpsMultiplier);
  // Verify that repeated probes aren't sent.
  probes =
      probe_controller_->SetEstimatedBitrate(100 * kMbpsMultiplier, NowMs());
  EXPECT_EQ(probes.size(), 0u);
}

TEST_F(ProbeControllerTest, TestAllocatedBitrateCap) {
  const int64_t kMbpsMultiplier = 1000000;
  const int64_t kMaxBitrateBps = 100 * kMbpsMultiplier;
  auto probes = probe_controller_->SetBitrates(
      kMinBitrateBps, 10 * kMbpsMultiplier, kMaxBitrateBps, NowMs());

  // Configure ALR for periodic probing.
  probe_controller_->EnablePeriodicAlrProbing(true);
  int64_t alr_start_time = clock_.TimeInMilliseconds();
  probe_controller_->SetAlrStartTimeMs(alr_start_time);

  int64_t estimated_bitrate_bps = kMaxBitrateBps / 10;
  probes =
      probe_controller_->SetEstimatedBitrate(estimated_bitrate_bps, NowMs());

  // Set a max allocated bitrate below the current estimate.
  int64_t max_allocated_bps = estimated_bitrate_bps - 1 * kMbpsMultiplier;
  probes =
      probe_controller_->OnMaxTotalAllocatedBitrate(max_allocated_bps, NowMs());
  EXPECT_TRUE(probes.empty());  // No probe since lower than current max.

  // Probes such as ALR capped at 2x the max allocation limit.
  clock_.AdvanceTimeMilliseconds(5000);
  probes = probe_controller_->Process(NowMs());
  EXPECT_EQ(probes.size(), 1u);
  EXPECT_EQ(probes[0].target_data_rate.bps(), 2 * max_allocated_bps);

  // Remove allocation limit.
  EXPECT_TRUE(
      probe_controller_->OnMaxTotalAllocatedBitrate(0, NowMs()).empty());
  clock_.AdvanceTimeMilliseconds(5000);
  probes = probe_controller_->Process(NowMs());
  EXPECT_EQ(probes.size(), 1u);
  EXPECT_EQ(probes[0].target_data_rate.bps(), estimated_bitrate_bps * 2);
}

TEST_F(ProbeControllerTest, ConfigurableProbingFieldTrial) {
  test::ScopedFieldTrials trials(
      "WebRTC-Bwe-ProbingConfiguration/"
      "p1:2,p2:5,step_size:3,further_probe_threshold:0.8,"
      "alloc_p1:2,alloc_p2/");
  probe_controller_.reset(
      new ProbeController(&field_trial_config_, &mock_rtc_event_log));
  auto probes = probe_controller_->SetBitrates(kMinBitrateBps, kStartBitrateBps,
                                               5000000, NowMs());
  EXPECT_EQ(probes.size(), 2u);
  EXPECT_EQ(probes[0].target_data_rate.bps(), 600);
  EXPECT_EQ(probes[1].target_data_rate.bps(), 1500);

  // Repeated probe should only be sent when estimated bitrate climbs above
  // 0.8 * 5 * kStartBitrateBps = 1200.
  probes = probe_controller_->SetEstimatedBitrate(1100, NowMs());
  EXPECT_EQ(probes.size(), 0u);

  probes = probe_controller_->SetEstimatedBitrate(1250, NowMs());
  EXPECT_EQ(probes.size(), 1u);
  EXPECT_EQ(probes[0].target_data_rate.bps(), 3 * 1250);

  clock_.AdvanceTimeMilliseconds(5000);
  probes = probe_controller_->Process(NowMs());

  probes = probe_controller_->OnMaxTotalAllocatedBitrate(200000, NowMs());
  EXPECT_EQ(probes.size(), 1u);
  EXPECT_EQ(probes[0].target_data_rate.bps(), 400000);
}

}  // namespace test
}  // namespace webrtc
