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

#include "absl/memory/memory.h"
#include "modules/congestion_controller/pcc/bitrate_controller.h"

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,
                           absl::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::bps(
      std::max(0.0, bandwith_estimate.bps() + rate_change_bps));
}

}  // namespace pcc
}  // namespace webrtc
