/*
 *  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 <algorithm>
#include <cmath>
#include <cstdlib>
#include <memory>
#include <utility>
#include <vector>


namespace webrtc {
namespace pcc {

PccBitrateController::PccBitrateController(double initial_conversion_factor,
                                           double initial_dynamic_boundary,
                                           double dynamic_boundary_increment,
                                           double rtt_gradient_coefficient,
                                           double loss_coefficient,
                                           double throughput_coefficient,
                                           double throughput_power,
                                           double rtt_gradient_threshold,
                                           double delay_gradient_negative_bound)
    : PccBitrateController(initial_conversion_factor,
                           initial_dynamic_boundary,
                           dynamic_boundary_increment,
                           std::make_unique<ModifiedVivaceUtilityFunction>(
                               rtt_gradient_coefficient,
                               loss_coefficient,
                               throughput_coefficient,
                               throughput_power,
                               rtt_gradient_threshold,
                               delay_gradient_negative_bound)) {}

PccBitrateController::PccBitrateController(
    double initial_conversion_factor,
    double initial_dynamic_boundary,
    double dynamic_boundary_increment,
    std::unique_ptr<PccUtilityFunctionInterface> utility_function)
    : consecutive_boundary_adjustments_number_(0),
      initial_dynamic_boundary_(initial_dynamic_boundary),
      dynamic_boundary_increment_(dynamic_boundary_increment),
      utility_function_(std::move(utility_function)),
      step_size_adjustments_number_(0),
      initial_conversion_factor_(initial_conversion_factor) {}

PccBitrateController::~PccBitrateController() = default;

double PccBitrateController::ComputeStepSize(double utility_gradient) {
  // Computes number of consecutive step size adjustments.
  if (utility_gradient > 0) {
    step_size_adjustments_number_ =
        std::max<int64_t>(step_size_adjustments_number_ + 1, 1);
  } else if (utility_gradient < 0) {
    step_size_adjustments_number_ =
        std::min<int64_t>(step_size_adjustments_number_ - 1, -1);
  } else {
    step_size_adjustments_number_ = 0;
  }
  // Computes step size amplifier.
  int64_t step_size_amplifier = 1;
  if (std::abs(step_size_adjustments_number_) <= 3) {
    step_size_amplifier =
        std::max<int64_t>(std::abs(step_size_adjustments_number_), 1);
  } else {
    step_size_amplifier = 2 * std::abs(step_size_adjustments_number_) - 3;
  }
  return step_size_amplifier * initial_conversion_factor_;
}

double PccBitrateController::ApplyDynamicBoundary(double rate_change,
                                                  double bitrate) {
  double rate_change_abs = std::abs(rate_change);
  int64_t rate_change_sign = (rate_change > 0) ? 1 : -1;
  if (consecutive_boundary_adjustments_number_ * rate_change_sign < 0) {
    consecutive_boundary_adjustments_number_ = 0;
  }
  double dynamic_change_boundary =
      initial_dynamic_boundary_ +
      std::abs(consecutive_boundary_adjustments_number_) *
          dynamic_boundary_increment_;
  double boundary = bitrate * dynamic_change_boundary;
  if (rate_change_abs > boundary) {
    consecutive_boundary_adjustments_number_ += rate_change_sign;
    return boundary * rate_change_sign;
  }
  // Rate change smaller than boundary. Reset boundary to the smallest possible
  // that would allow the change.
  while (rate_change_abs <= boundary &&
         consecutive_boundary_adjustments_number_ * rate_change_sign > 0) {
    consecutive_boundary_adjustments_number_ -= rate_change_sign;
    dynamic_change_boundary =
        initial_dynamic_boundary_ +
        std::abs(consecutive_boundary_adjustments_number_) *
            dynamic_boundary_increment_;
    boundary = bitrate * dynamic_change_boundary;
  }
  consecutive_boundary_adjustments_number_ += rate_change_sign;
  return rate_change;
}

absl::optional<DataRate>
PccBitrateController::ComputeRateUpdateForSlowStartMode(
    const PccMonitorInterval& monitor_interval) {
  double utility_value = utility_function_->Compute(monitor_interval);
  if (previous_utility_.has_value() && utility_value <= previous_utility_) {
    return absl::nullopt;
  }
  previous_utility_ = utility_value;
  return monitor_interval.GetTargetSendingRate();
}

DataRate PccBitrateController::ComputeRateUpdateForOnlineLearningMode(
    const std::vector<PccMonitorInterval>& intervals,
    DataRate bandwith_estimate) {
  double first_utility = utility_function_->Compute(intervals[0]);
  double second_utility = utility_function_->Compute(intervals[1]);
  double first_bitrate_bps = intervals[0].GetTargetSendingRate().bps();
  double second_bitrate_bps = intervals[1].GetTargetSendingRate().bps();
  double gradient = (first_utility - second_utility) /
                    (first_bitrate_bps - second_bitrate_bps);
  double rate_change_bps = gradient * ComputeStepSize(gradient);  // delta_r
  rate_change_bps =
      ApplyDynamicBoundary(rate_change_bps, bandwith_estimate.bps());
  return DataRate::BitsPerSec(
      std::max(0.0, bandwith_estimate.bps() + rate_change_bps));
}

}  // namespace pcc
}  // namespace webrtc
