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

#include <algorithm>
#include <cassert>
#include <cmath>

#include "webrtc/modules/remote_bitrate_estimator/test/bwe_test_logging.h"

namespace webrtc {

static const int64_t kDefaultRttMs = 200;
static const int64_t kLogIntervalMs = 1000;
static const double kWithinIncomingBitrateHysteresis = 1.05;

AimdRateControl::AimdRateControl(uint32_t min_bitrate_bps)
    : min_configured_bitrate_bps_(min_bitrate_bps),
      max_configured_bitrate_bps_(30000000),
      current_bitrate_bps_(max_configured_bitrate_bps_),
      max_hold_rate_bps_(0),
      avg_max_bitrate_kbps_(-1.0f),
      var_max_bitrate_kbps_(0.4f),
      rate_control_state_(kRcHold),
      came_from_state_(kRcDecrease),
      rate_control_region_(kRcMaxUnknown),
      time_last_bitrate_change_(-1),
      current_input_(kBwNormal, 0, 1.0),
      updated_(false),
      time_first_incoming_estimate_(-1),
      bitrate_is_initialized_(false),
      beta_(0.9f),
      rtt_(kDefaultRttMs),
      time_of_last_log_(-1) {}

RateControlType AimdRateControl::GetControlType() const {
  return kAimdControl;
}

uint32_t AimdRateControl::GetMinBitrate() const {
  return min_configured_bitrate_bps_;
}

bool AimdRateControl::ValidEstimate() const {
  return bitrate_is_initialized_;
}

int64_t AimdRateControl::GetFeedbackInterval() const {
  // Estimate how often we can send RTCP if we allocate up to 5% of bandwidth
  // to feedback.
  static const int kRtcpSize = 80;
  int64_t interval = static_cast<int64_t>(
      kRtcpSize * 8.0 * 1000.0 / (0.05 * current_bitrate_bps_) + 0.5);
  const int64_t kMinFeedbackIntervalMs = 200;
  return std::min(std::max(interval, kMinFeedbackIntervalMs),
                  kMaxFeedbackIntervalMs);
}

bool AimdRateControl::TimeToReduceFurther(int64_t time_now,
                                          uint32_t incoming_bitrate_bps) const {
  const int64_t bitrate_reduction_interval =
      std::max<int64_t>(std::min<int64_t>(rtt_, 200), 10);
  if (time_now - time_last_bitrate_change_ >= bitrate_reduction_interval) {
    return true;
  }
  if (ValidEstimate()) {
    const int threshold = static_cast<int>(kWithinIncomingBitrateHysteresis *
                                           incoming_bitrate_bps);
    const int bitrate_difference = LatestEstimate() - incoming_bitrate_bps;
    return bitrate_difference > threshold;
  }
  return false;
}

uint32_t AimdRateControl::LatestEstimate() const {
  return current_bitrate_bps_;
}

uint32_t AimdRateControl::UpdateBandwidthEstimate(int64_t now_ms) {
  current_bitrate_bps_ = ChangeBitrate(current_bitrate_bps_,
                                       current_input_._incomingBitRate,
                                       now_ms);
  if (now_ms - time_of_last_log_ > kLogIntervalMs) {
    time_of_last_log_ = now_ms;
  }
  return current_bitrate_bps_;
}

void AimdRateControl::SetRtt(int64_t rtt) {
  rtt_ = rtt;
}

RateControlRegion AimdRateControl::Update(const RateControlInput* input,
                                          int64_t now_ms) {
  assert(input);

  // Set the initial bit rate value to what we're receiving the first half
  // second.
  if (!bitrate_is_initialized_) {
    if (time_first_incoming_estimate_ < 0) {
      if (input->_incomingBitRate > 0) {
        time_first_incoming_estimate_ = now_ms;
      }
    } else if (now_ms - time_first_incoming_estimate_ > 500 &&
               input->_incomingBitRate > 0) {
      current_bitrate_bps_ = input->_incomingBitRate;
      bitrate_is_initialized_ = true;
    }
  }

  if (updated_ && current_input_._bwState == kBwOverusing) {
    // Only update delay factor and incoming bit rate. We always want to react
    // on an over-use.
    current_input_._noiseVar = input->_noiseVar;
    current_input_._incomingBitRate = input->_incomingBitRate;
  } else {
    updated_ = true;
    current_input_ = *input;
  }
  return rate_control_region_;
}

void AimdRateControl::SetEstimate(int bitrate_bps, int64_t now_ms) {
  updated_ = true;
  bitrate_is_initialized_ = true;
  current_bitrate_bps_ = ChangeBitrate(bitrate_bps, bitrate_bps, now_ms);
}

uint32_t AimdRateControl::ChangeBitrate(uint32_t current_bitrate_bps,
                                        uint32_t incoming_bitrate_bps,
                                        int64_t now_ms) {
  BWE_TEST_LOGGING_PLOT("estimated_incoming#1", -1,
                        incoming_bitrate_bps / 1000);
  if (!updated_) {
    return current_bitrate_bps_;
  }
  updated_ = false;
  ChangeState(current_input_, now_ms);
  // Calculated here because it's used in multiple places.
  const float incoming_bitrate_kbps = incoming_bitrate_bps / 1000.0f;
  // Calculate the max bit rate std dev given the normalized
  // variance and the current incoming bit rate.
  const float std_max_bit_rate = sqrt(var_max_bitrate_kbps_ *
                                      avg_max_bitrate_kbps_);
  bool fast_recovery_after_hold = false;
  switch (rate_control_state_) {
    case kRcHold: {
      max_hold_rate_bps_ = std::max(max_hold_rate_bps_, incoming_bitrate_bps);
      break;
    }
    case kRcIncrease: {
      if (avg_max_bitrate_kbps_ >= 0) {
        if (incoming_bitrate_kbps > avg_max_bitrate_kbps_ +
            3 * std_max_bit_rate) {
          ChangeRegion(kRcMaxUnknown);
          avg_max_bitrate_kbps_ = -1.0;
        } else if (incoming_bitrate_kbps > avg_max_bitrate_kbps_ +
            2.5 * std_max_bit_rate) {
          ChangeRegion(kRcAboveMax);
        }
      }
      if (rate_control_region_ == kRcNearMax) {
        // Approximate the over-use estimator delay to 100 ms.
        const int64_t response_time = rtt_ + 100;
        uint32_t additive_increase_bps = AdditiveRateIncrease(
            now_ms, time_last_bitrate_change_, response_time);
        BWE_TEST_LOGGING_PLOT("add_increase#1", -1,
                              additive_increase_bps / 1000);
        current_bitrate_bps += additive_increase_bps;

      } else {
        uint32_t multiplicative_increase_bps = MultiplicativeRateIncrease(
            now_ms, time_last_bitrate_change_, current_bitrate_bps);
        BWE_TEST_LOGGING_PLOT("mult_increase#1", -1,
                              multiplicative_increase_bps / 1000);
        current_bitrate_bps += multiplicative_increase_bps;
      }

      if (max_hold_rate_bps_ > 0 &&
          beta_ * max_hold_rate_bps_ > current_bitrate_bps) {
        current_bitrate_bps = static_cast<uint32_t>(beta_ * max_hold_rate_bps_);
        avg_max_bitrate_kbps_ = beta_ * max_hold_rate_bps_ / 1000.0f;
        ChangeRegion(kRcNearMax);
        fast_recovery_after_hold = true;
      }
      max_hold_rate_bps_ = 0;
      time_last_bitrate_change_ = now_ms;
      break;
    }
    case kRcDecrease: {
      if (incoming_bitrate_bps < min_configured_bitrate_bps_) {
        current_bitrate_bps = min_configured_bitrate_bps_;
      } else {
        // Set bit rate to something slightly lower than max
        // to get rid of any self-induced delay.
        current_bitrate_bps = static_cast<uint32_t>(beta_ *
                                                    incoming_bitrate_bps + 0.5);
        if (current_bitrate_bps > current_bitrate_bps_) {
          // Avoid increasing the rate when over-using.
          if (rate_control_region_ != kRcMaxUnknown) {
            current_bitrate_bps = static_cast<uint32_t>(
                beta_ * avg_max_bitrate_kbps_ * 1000 + 0.5f);
          }
          current_bitrate_bps = std::min(current_bitrate_bps,
                                         current_bitrate_bps_);
        }
        ChangeRegion(kRcNearMax);

        if (incoming_bitrate_kbps < avg_max_bitrate_kbps_ -
            3 * std_max_bit_rate) {
          avg_max_bitrate_kbps_ = -1.0f;
        }

        UpdateMaxBitRateEstimate(incoming_bitrate_kbps);
      }
      // Stay on hold until the pipes are cleared.
      ChangeState(kRcHold);
      time_last_bitrate_change_ = now_ms;
      break;
    }
    default:
      assert(false);
  }
  if (!fast_recovery_after_hold && (incoming_bitrate_bps > 100000 ||
      current_bitrate_bps > 150000) &&
      current_bitrate_bps > 1.5 * incoming_bitrate_bps) {
    // Allow changing the bit rate if we are operating at very low rates
    // Don't change the bit rate if the send side is too far off
    current_bitrate_bps = current_bitrate_bps_;
    time_last_bitrate_change_ = now_ms;
  }
  return current_bitrate_bps;
}

uint32_t AimdRateControl::MultiplicativeRateIncrease(
    int64_t now_ms, int64_t last_ms, uint32_t current_bitrate_bps) const {
  double alpha = 1.08;
  if (last_ms > -1) {
    int time_since_last_update_ms = std::min(static_cast<int>(now_ms - last_ms),
                                             1000);
    alpha = pow(alpha,  time_since_last_update_ms / 1000.0);
  }
  uint32_t multiplicative_increase_bps = std::max(
      current_bitrate_bps * (alpha - 1.0), 1000.0);
  return multiplicative_increase_bps;
}

uint32_t AimdRateControl::AdditiveRateIncrease(
    int64_t now_ms, int64_t last_ms, int64_t response_time_ms) const {
  assert(response_time_ms > 0);
  double beta = 0.0;
  if (last_ms > 0) {
    beta = std::min((now_ms - last_ms) /
                    static_cast<double>(response_time_ms), 1.0);
  }
  double bits_per_frame = static_cast<double>(current_bitrate_bps_) / 30.0;
  double packets_per_frame = std::ceil(bits_per_frame / (8.0 * 1200.0));
  double avg_packet_size_bits = bits_per_frame / packets_per_frame;
  uint32_t additive_increase_bps = std::max(
      1000.0, beta * avg_packet_size_bits);
  return additive_increase_bps;
}

void AimdRateControl::UpdateMaxBitRateEstimate(float incoming_bitrate_kbps) {
  const float alpha = 0.05f;
  if (avg_max_bitrate_kbps_ == -1.0f) {
    avg_max_bitrate_kbps_ = incoming_bitrate_kbps;
  } else {
    avg_max_bitrate_kbps_ = (1 - alpha) * avg_max_bitrate_kbps_ +
        alpha * incoming_bitrate_kbps;
  }
  // Estimate the max bit rate variance and normalize the variance
  // with the average max bit rate.
  const float norm = std::max(avg_max_bitrate_kbps_, 1.0f);
  var_max_bitrate_kbps_ = (1 - alpha) * var_max_bitrate_kbps_ +
      alpha * (avg_max_bitrate_kbps_ - incoming_bitrate_kbps) *
          (avg_max_bitrate_kbps_ - incoming_bitrate_kbps) / norm;
  // 0.4 ~= 14 kbit/s at 500 kbit/s
  if (var_max_bitrate_kbps_ < 0.4f) {
    var_max_bitrate_kbps_ = 0.4f;
  }
  // 2.5f ~= 35 kbit/s at 500 kbit/s
  if (var_max_bitrate_kbps_ > 2.5f) {
    var_max_bitrate_kbps_ = 2.5f;
  }
}

void AimdRateControl::ChangeState(const RateControlInput& input,
                                  int64_t now_ms) {
  switch (current_input_._bwState) {
    case kBwNormal:
      if (rate_control_state_ == kRcHold) {
        time_last_bitrate_change_ = now_ms;
        ChangeState(kRcIncrease);
      }
      break;
    case kBwOverusing:
      if (rate_control_state_ != kRcDecrease) {
        ChangeState(kRcDecrease);
      }
      break;
    case kBwUnderusing:
      ChangeState(kRcHold);
      break;
    default:
      assert(false);
  }
}

void AimdRateControl::ChangeRegion(RateControlRegion region) {
  rate_control_region_ = region;
  switch (rate_control_region_) {
    case kRcAboveMax:
    case kRcMaxUnknown:
      beta_ = 0.9f;
      break;
    case kRcNearMax:
      beta_ = 0.95f;
      break;
    default:
      assert(false);
  }
}

void AimdRateControl::ChangeState(RateControlState new_state) {
  came_from_state_ = rate_control_state_;
  rate_control_state_ = new_state;
}
}  // namespace webrtc
