/*
 *  Copyright (c) 2018 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/pcc/bitrate_controller.h"

#include <utility>

#include "absl/memory/memory.h"
#include "modules/congestion_controller/pcc/monitor_interval.h"
#include "test/gmock.h"
#include "test/gtest.h"

namespace webrtc {
namespace pcc {
namespace test {
namespace {
constexpr double kInitialConversionFactor = 1;
constexpr double kInitialDynamicBoundary = 0.05;
constexpr double kDynamicBoundaryIncrement = 0.1;

constexpr double kDelayGradientCoefficient = 900;
constexpr double kLossCoefficient = 11.35;
constexpr double kThroughputCoefficient = 500 * 1000;
constexpr double kThroughputPower = 0.99;
constexpr double kDelayGradientThreshold = 0.01;
constexpr double kDelayGradientNegativeBound = 10;

const DataRate kTargetSendingRate = DataRate::kbps(300);
const double kEpsilon = 0.05;
const Timestamp kStartTime = Timestamp::us(0);
const TimeDelta kPacketsDelta = TimeDelta::ms(1);
const TimeDelta kIntervalDuration = TimeDelta::ms(1000);
const TimeDelta kDefaultRtt = TimeDelta::ms(1000);
const DataSize kDefaultDataSize = DataSize::bytes(100);

std::vector<PacketResult> CreatePacketResults(
    const std::vector<Timestamp>& packets_send_times,
    const std::vector<Timestamp>& packets_received_times = {},
    const std::vector<DataSize>& packets_sizes = {}) {
  std::vector<PacketResult> packet_results;
  PacketResult packet_result;
  SentPacket sent_packet;
  for (size_t i = 0; i < packets_send_times.size(); ++i) {
    sent_packet.send_time = packets_send_times[i];
    if (packets_sizes.empty()) {
      sent_packet.size = kDefaultDataSize;
    } else {
      sent_packet.size = packets_sizes[i];
    }
    packet_result.sent_packet = sent_packet;
    if (packets_received_times.empty()) {
      packet_result.receive_time = packets_send_times[i] + kDefaultRtt;
    } else {
      packet_result.receive_time = packets_received_times[i];
    }
    packet_results.push_back(packet_result);
  }
  return packet_results;
}

class MockUtilityFunction : public PccUtilityFunctionInterface {
 public:
  MOCK_CONST_METHOD1(Compute,
                     double(const PccMonitorInterval& monitor_interval));
};

}  // namespace

TEST(PccBitrateControllerTest, IncreaseRateWhenNoChangesForTestBitrates) {
  PccBitrateController bitrate_controller(
      kInitialConversionFactor, kInitialDynamicBoundary,
      kDynamicBoundaryIncrement, kDelayGradientCoefficient, kLossCoefficient,
      kThroughputCoefficient, kThroughputPower, kDelayGradientThreshold,
      kDelayGradientNegativeBound);
  VivaceUtilityFunction utility_function(
      kDelayGradientCoefficient, kLossCoefficient, kThroughputCoefficient,
      kThroughputPower, kDelayGradientThreshold, kDelayGradientNegativeBound);
  std::vector<PccMonitorInterval> monitor_block{
      PccMonitorInterval(kTargetSendingRate * (1 + kEpsilon), kStartTime,
                         kIntervalDuration),
      PccMonitorInterval(kTargetSendingRate * (1 - kEpsilon),
                         kStartTime + kIntervalDuration, kIntervalDuration)};
  monitor_block[0].OnPacketsFeedback(
      CreatePacketResults({kStartTime + kPacketsDelta,
                           kStartTime + kIntervalDuration + kPacketsDelta,
                           kStartTime + 3 * kIntervalDuration},
                          {}, {}));
  monitor_block[1].OnPacketsFeedback(
      CreatePacketResults({kStartTime + kPacketsDelta,
                           kStartTime + kIntervalDuration + kPacketsDelta,
                           kStartTime + 3 * kIntervalDuration},
                          {}, {}));
  // For both of the monitor intervals there were no change in rtt gradient
  // and in packet loss. Since the only difference is in the sending rate,
  // the higher sending rate should be chosen by congestion controller.
  EXPECT_GT(bitrate_controller
                .ComputeRateUpdateForOnlineLearningMode(monitor_block,
                                                        kTargetSendingRate)
                .bps(),
            kTargetSendingRate.bps());
}

TEST(PccBitrateControllerTest, NoChangesWhenUtilityFunctionDoesntChange) {
  std::unique_ptr<MockUtilityFunction> mock_utility_function =
      absl::make_unique<MockUtilityFunction>();
  EXPECT_CALL(*mock_utility_function, Compute(::testing::_))
      .Times(2)
      .WillOnce(::testing::Return(100))
      .WillOnce(::testing::Return(100));

  PccBitrateController bitrate_controller(
      kInitialConversionFactor, kInitialDynamicBoundary,
      kDynamicBoundaryIncrement, std::move(mock_utility_function));
  std::vector<PccMonitorInterval> monitor_block{
      PccMonitorInterval(kTargetSendingRate * (1 + kEpsilon), kStartTime,
                         kIntervalDuration),
      PccMonitorInterval(kTargetSendingRate * (1 - kEpsilon),
                         kStartTime + kIntervalDuration, kIntervalDuration)};
  // To complete collecting feedback within monitor intervals.
  monitor_block[0].OnPacketsFeedback(
      CreatePacketResults({kStartTime + 3 * kIntervalDuration}, {}, {}));
  monitor_block[1].OnPacketsFeedback(
      CreatePacketResults({kStartTime + 3 * kIntervalDuration}, {}, {}));
  // Because we don't have any packets inside of monitor intervals, utility
  // function should be zero for both of them and the sending rate should not
  // change.
  EXPECT_EQ(bitrate_controller
                .ComputeRateUpdateForOnlineLearningMode(monitor_block,
                                                        kTargetSendingRate)
                .bps(),
            kTargetSendingRate.bps());
}

TEST(PccBitrateControllerTest, NoBoundaryWhenSmallGradient) {
  std::unique_ptr<MockUtilityFunction> mock_utility_function =
      absl::make_unique<MockUtilityFunction>();
  constexpr double kFirstMonitorIntervalUtility = 0;
  const double kSecondMonitorIntervalUtility =
      2 * kTargetSendingRate.bps() * kEpsilon;

  EXPECT_CALL(*mock_utility_function, Compute(::testing::_))
      .Times(2)
      .WillOnce(::testing::Return(kFirstMonitorIntervalUtility))
      .WillOnce(::testing::Return(kSecondMonitorIntervalUtility));

  PccBitrateController bitrate_controller(
      kInitialConversionFactor, kInitialDynamicBoundary,
      kDynamicBoundaryIncrement, std::move(mock_utility_function));
  std::vector<PccMonitorInterval> monitor_block{
      PccMonitorInterval(kTargetSendingRate * (1 + kEpsilon), kStartTime,
                         kIntervalDuration),
      PccMonitorInterval(kTargetSendingRate * (1 - kEpsilon),
                         kStartTime + kIntervalDuration, kIntervalDuration)};
  // To complete collecting feedback within monitor intervals.
  monitor_block[0].OnPacketsFeedback(
      CreatePacketResults({kStartTime + 3 * kIntervalDuration}, {}, {}));
  monitor_block[1].OnPacketsFeedback(
      CreatePacketResults({kStartTime + 3 * kIntervalDuration}, {}, {}));

  double gradient =
      (kFirstMonitorIntervalUtility - kSecondMonitorIntervalUtility) /
      (kTargetSendingRate.bps() * 2 * kEpsilon);
  // When the gradient is small we don't hit the dynamic boundary.
  EXPECT_EQ(bitrate_controller
                .ComputeRateUpdateForOnlineLearningMode(monitor_block,
                                                        kTargetSendingRate)
                .bps(),
            kTargetSendingRate.bps() + kInitialConversionFactor * gradient);
}

TEST(PccBitrateControllerTest, FaceBoundaryWhenLargeGradient) {
  std::unique_ptr<MockUtilityFunction> mock_utility_function =
      absl::make_unique<MockUtilityFunction>();
  constexpr double kFirstMonitorIntervalUtility = 0;
  const double kSecondMonitorIntervalUtility =
      10 * kInitialDynamicBoundary * kTargetSendingRate.bps() * 2 *
      kTargetSendingRate.bps() * kEpsilon;

  EXPECT_CALL(*mock_utility_function, Compute(::testing::_))
      .Times(4)
      .WillOnce(::testing::Return(kFirstMonitorIntervalUtility))
      .WillOnce(::testing::Return(kSecondMonitorIntervalUtility))
      .WillOnce(::testing::Return(kFirstMonitorIntervalUtility))
      .WillOnce(::testing::Return(kSecondMonitorIntervalUtility));

  PccBitrateController bitrate_controller(
      kInitialConversionFactor, kInitialDynamicBoundary,
      kDynamicBoundaryIncrement, std::move(mock_utility_function));
  std::vector<PccMonitorInterval> monitor_block{
      PccMonitorInterval(kTargetSendingRate * (1 + kEpsilon), kStartTime,
                         kIntervalDuration),
      PccMonitorInterval(kTargetSendingRate * (1 - kEpsilon),
                         kStartTime + kIntervalDuration, kIntervalDuration)};
  // To complete collecting feedback within monitor intervals.
  monitor_block[0].OnPacketsFeedback(
      CreatePacketResults({kStartTime + 3 * kIntervalDuration}, {}, {}));
  monitor_block[1].OnPacketsFeedback(
      CreatePacketResults({kStartTime + 3 * kIntervalDuration}, {}, {}));
  // The utility function gradient is too big and we hit the dynamic boundary.
  EXPECT_EQ(bitrate_controller.ComputeRateUpdateForOnlineLearningMode(
                monitor_block, kTargetSendingRate),
            kTargetSendingRate * (1 - kInitialDynamicBoundary));
  // For the second time we hit the dynamic boundary in the same direction, the
  // boundary should increase.
  EXPECT_EQ(bitrate_controller
                .ComputeRateUpdateForOnlineLearningMode(monitor_block,
                                                        kTargetSendingRate)
                .bps(),
            kTargetSendingRate.bps() *
                (1 - kInitialDynamicBoundary - kDynamicBoundaryIncrement));
}

TEST(PccBitrateControllerTest, SlowStartMode) {
  std::unique_ptr<MockUtilityFunction> mock_utility_function =
      absl::make_unique<MockUtilityFunction>();
  constexpr double kFirstUtilityFunction = 1000;
  EXPECT_CALL(*mock_utility_function, Compute(::testing::_))
      .Times(4)
      // For first 3 calls we expect to stay in the SLOW_START mode and double
      // the sending rate since the utility function increases its value. For
      // the last call utility function decreases its value, this means that
      // we should not double the sending rate and exit SLOW_START mode.
      .WillOnce(::testing::Return(kFirstUtilityFunction))
      .WillOnce(::testing::Return(kFirstUtilityFunction + 1))
      .WillOnce(::testing::Return(kFirstUtilityFunction + 2))
      .WillOnce(::testing::Return(kFirstUtilityFunction + 1));

  PccBitrateController bitrate_controller(
      kInitialConversionFactor, kInitialDynamicBoundary,
      kDynamicBoundaryIncrement, std::move(mock_utility_function));
  std::vector<PccMonitorInterval> monitor_block{PccMonitorInterval(
      2 * kTargetSendingRate, kStartTime, kIntervalDuration)};
  // To complete collecting feedback within monitor intervals.
  monitor_block[0].OnPacketsFeedback(
      CreatePacketResults({kStartTime + 3 * kIntervalDuration}, {}, {}));
  EXPECT_EQ(
      bitrate_controller.ComputeRateUpdateForSlowStartMode(monitor_block[0]),
      kTargetSendingRate * 2);
  EXPECT_EQ(
      bitrate_controller.ComputeRateUpdateForSlowStartMode(monitor_block[0]),
      kTargetSendingRate * 2);
  EXPECT_EQ(
      bitrate_controller.ComputeRateUpdateForSlowStartMode(monitor_block[0]),
      kTargetSendingRate * 2);
  EXPECT_EQ(
      bitrate_controller.ComputeRateUpdateForSlowStartMode(monitor_block[0]),
      absl::nullopt);
}

TEST(PccBitrateControllerTest, StepSizeIncrease) {
  std::unique_ptr<MockUtilityFunction> mock_utility_function =
      absl::make_unique<MockUtilityFunction>();
  constexpr double kFirstMiUtilityFunction = 0;
  const double kSecondMiUtilityFunction =
      2 * kTargetSendingRate.bps() * kEpsilon;

  EXPECT_CALL(*mock_utility_function, Compute(::testing::_))
      .Times(4)
      .WillOnce(::testing::Return(kFirstMiUtilityFunction))
      .WillOnce(::testing::Return(kSecondMiUtilityFunction))
      .WillOnce(::testing::Return(kFirstMiUtilityFunction))
      .WillOnce(::testing::Return(kSecondMiUtilityFunction));
  std::vector<PccMonitorInterval> monitor_block{
      PccMonitorInterval(kTargetSendingRate * (1 + kEpsilon), kStartTime,
                         kIntervalDuration),
      PccMonitorInterval(kTargetSendingRate * (1 - kEpsilon),
                         kStartTime + kIntervalDuration, kIntervalDuration)};
  // To complete collecting feedback within monitor intervals.
  monitor_block[0].OnPacketsFeedback(
      CreatePacketResults({kStartTime + 3 * kIntervalDuration}, {}, {}));
  monitor_block[1].OnPacketsFeedback(
      CreatePacketResults({kStartTime + 3 * kIntervalDuration}, {}, {}));

  double gradient = (kFirstMiUtilityFunction - kSecondMiUtilityFunction) /
                    (kTargetSendingRate.bps() * 2 * kEpsilon);
  PccBitrateController bitrate_controller(
      kInitialConversionFactor, kInitialDynamicBoundary,
      kDynamicBoundaryIncrement, std::move(mock_utility_function));
  // If we are moving in the same direction - the step size should increase.
  EXPECT_EQ(bitrate_controller
                .ComputeRateUpdateForOnlineLearningMode(monitor_block,
                                                        kTargetSendingRate)
                .bps(),
            kTargetSendingRate.bps() + kInitialConversionFactor * gradient);
  EXPECT_EQ(bitrate_controller
                .ComputeRateUpdateForOnlineLearningMode(monitor_block,
                                                        kTargetSendingRate)
                .bps(),
            kTargetSendingRate.bps() + 2 * kInitialConversionFactor * gradient);
}

}  // namespace test
}  // namespace pcc
}  // namespace webrtc
