/*
 *  Copyright (c) 2015 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.
 *
 */

//  Implementation of Network-Assisted Dynamic Adaptation's (NADA's) proposal.
//  Version according to Draft Document (mentioned in references)
//  http://tools.ietf.org/html/draft-zhu-rmcat-nada-06
//  From March 26, 2015.

#include <math.h>
#include <stddef.h>
#include <algorithm>
#include <cstdint>
#include <list>
#include <vector>

#include "modules/remote_bitrate_estimator/test/estimators/nada.h"
#include "modules/rtp_rtcp/include/receive_statistics.h"
#include "rtc_base/arraysize.h"

namespace webrtc {
namespace testing {
namespace bwe {

namespace {
// Used as an upper bound for calling AcceleratedRampDown.
const float kMaxCongestionSignalMs =
    40.0f + NadaBweSender::kMinNadaBitrateKbps / 15;
}  // namespace

const int NadaBweSender::kMinNadaBitrateKbps = 50;
const int64_t NadaBweReceiver::kReceivingRateTimeWindowMs = 500;

NadaBweReceiver::NadaBweReceiver(int flow_id)
    : BweReceiver(flow_id, kReceivingRateTimeWindowMs),
      clock_(0),
      last_feedback_ms_(0),
      recv_stats_(ReceiveStatistics::Create(&clock_)),
      baseline_delay_ms_(10000),  // Initialized as an upper bound.
      delay_signal_ms_(0),
      last_congestion_signal_ms_(0),
      last_delays_index_(0),
      exp_smoothed_delay_ms_(-1),
      est_queuing_delay_signal_ms_(0) {}

NadaBweReceiver::~NadaBweReceiver() {}

void NadaBweReceiver::ReceivePacket(int64_t arrival_time_ms,
                                    const MediaPacket& media_packet) {
  const float kAlpha = 0.1f;                 // Used for exponential smoothing.
  const int64_t kDelayLowThresholdMs = 50;   // Referred as d_th.
  const int64_t kDelayMaxThresholdMs = 400;  // Referred as d_max.

  clock_.AdvanceTimeMilliseconds(arrival_time_ms - clock_.TimeInMilliseconds());
  recv_stats_->OnRtpPacket(media_packet.GetRtpPacket());
  // Refered as x_n.
  int64_t delay_ms = arrival_time_ms - media_packet.sender_timestamp_ms();

  // The min should be updated within the first 10 minutes.
  if (clock_.TimeInMilliseconds() < 10 * 60 * 1000) {
    baseline_delay_ms_ = std::min(baseline_delay_ms_, delay_ms);
  }

  delay_signal_ms_ = delay_ms - baseline_delay_ms_;  // Refered as d_n.
  const int kMedian = arraysize(last_delays_ms_);
  last_delays_ms_[(last_delays_index_++) % kMedian] = delay_signal_ms_;
  int size = std::min(last_delays_index_, kMedian);

  int64_t median_filtered_delay_ms_ = MedianFilter(last_delays_ms_, size);
  exp_smoothed_delay_ms_ = ExponentialSmoothingFilter(
      median_filtered_delay_ms_, exp_smoothed_delay_ms_, kAlpha);

  if (exp_smoothed_delay_ms_ < kDelayLowThresholdMs) {
    est_queuing_delay_signal_ms_ = exp_smoothed_delay_ms_;
  } else if (exp_smoothed_delay_ms_ < kDelayMaxThresholdMs) {
    est_queuing_delay_signal_ms_ = static_cast<int64_t>(
        pow((static_cast<double>(kDelayMaxThresholdMs -
                                 exp_smoothed_delay_ms_)) /
                (kDelayMaxThresholdMs - kDelayLowThresholdMs),
            4.0) *
        kDelayLowThresholdMs);
  } else {
    est_queuing_delay_signal_ms_ = 0;
  }

  // Log received packet information.
  BweReceiver::ReceivePacket(arrival_time_ms, media_packet);
}

FeedbackPacket* NadaBweReceiver::GetFeedback(int64_t now_ms) {
  const int64_t kPacketLossPenaltyMs = 1000;  // Referred as d_L.

  if (now_ms - last_feedback_ms_ < 100) {
    return NULL;
  }

  float loss_fraction = RecentPacketLossRatio();

  int64_t loss_signal_ms =
      static_cast<int64_t>(loss_fraction * kPacketLossPenaltyMs + 0.5f);
  int64_t congestion_signal_ms = est_queuing_delay_signal_ms_ + loss_signal_ms;

  float derivative = 0.0f;
  if (last_feedback_ms_ > 0) {
    derivative = (congestion_signal_ms - last_congestion_signal_ms_) /
                 static_cast<float>(now_ms - last_feedback_ms_);
  }
  last_feedback_ms_ = now_ms;
  last_congestion_signal_ms_ = congestion_signal_ms;

  int64_t corrected_send_time_ms = 0L;

  if (!received_packets_.empty()) {
    PacketIdentifierNode& latest = *(received_packets_.begin());
    corrected_send_time_ms =
        latest.send_time_ms + now_ms - latest.arrival_time_ms;
  }

  // Sends a tuple containing latest values of <d_hat_n, d_tilde_n, x_n, x'_n,
  // R_r> and additional information.
  return new NadaFeedback(flow_id_, now_ms * 1000, exp_smoothed_delay_ms_,
                          est_queuing_delay_signal_ms_, congestion_signal_ms,
                          derivative, RecentKbps(), corrected_send_time_ms);
}

// If size is even, the median is the average of the two middlemost numbers.
int64_t NadaBweReceiver::MedianFilter(int64_t* last_delays_ms, int size) {
  std::vector<int64_t> array_copy(last_delays_ms, last_delays_ms + size);
  std::nth_element(array_copy.begin(), array_copy.begin() + size / 2,
                   array_copy.end());
  if (size % 2 == 1) {
    // Typically, size = 5. For odd size values, right and left are equal.
    return array_copy.at(size / 2);
  }
  int64_t right = array_copy.at(size / 2);
  std::nth_element(array_copy.begin(), array_copy.begin() + (size - 1) / 2,
                   array_copy.end());
  int64_t left = array_copy.at((size - 1) / 2);
  return (left + right + 1) / 2;
}

int64_t NadaBweReceiver::ExponentialSmoothingFilter(int64_t new_value,
                                                    int64_t last_smoothed_value,
                                                    float alpha) {
  if (last_smoothed_value < 0) {
    return new_value;  // Handling initial case.
  }
  return static_cast<int64_t>(alpha * new_value +
                              (1.0f - alpha) * last_smoothed_value + 0.5f);
}

// Implementation according to Cisco's proposal by default.
NadaBweSender::NadaBweSender(int kbps, BitrateObserver* observer, Clock* clock)
    : BweSender(kbps),  // Referred as "Reference Rate" = R_n.,
      clock_(clock),
      observer_(observer),
      original_operating_mode_(true) {}

NadaBweSender::NadaBweSender(BitrateObserver* observer, Clock* clock)
    : BweSender(kMinNadaBitrateKbps),  // Referred as "Reference Rate" = R_n.
      clock_(clock),
      observer_(observer),
      original_operating_mode_(true) {}

NadaBweSender::~NadaBweSender() {}

int NadaBweSender::GetFeedbackIntervalMs() const {
  return 100;
}

void NadaBweSender::GiveFeedback(const FeedbackPacket& feedback) {
  const NadaFeedback& fb = static_cast<const NadaFeedback&>(feedback);

  // Following parameters might be optimized.
  const int64_t kQueuingDelayUpperBoundMs = 10;
  const float kDerivativeUpperBound =
      10.0f / std::max<int64_t>(1, min_feedback_delay_ms_);
  // In the modified version, a higher kMinUpperBound allows a higher d_hat
  // upper bound for calling AcceleratedRampUp.
  const float kProportionalityDelayBits = 20.0f;

  int64_t now_ms = clock_->TimeInMilliseconds();
  float delta_s = now_ms - last_feedback_ms_;
  last_feedback_ms_ = now_ms;
  // Update delta_0.
  min_feedback_delay_ms_ =
      std::min(min_feedback_delay_ms_, static_cast<int64_t>(delta_s));

  // Update RTT_0.
  int64_t rtt_ms = now_ms - fb.latest_send_time_ms();
  min_round_trip_time_ms_ = std::min(min_round_trip_time_ms_, rtt_ms);

  // Independent limits for AcceleratedRampUp conditions variables:
  // x_n, d_tilde and x'_n in the original implementation, plus
  // d_hat and receiving_rate in the modified one.
  // There should be no packet losses/marking, hence x_n == d_tilde.
  if (original_operating_mode_) {
    // Original if conditions and rate update.
    if (fb.congestion_signal() == fb.est_queuing_delay_signal_ms() &&
        fb.est_queuing_delay_signal_ms() < kQueuingDelayUpperBoundMs &&
        fb.derivative() < kDerivativeUpperBound) {
      AcceleratedRampUp(fb);
    } else {
      GradualRateUpdate(fb, delta_s, 1.0);
    }
  } else {
    // Modified if conditions and rate update; new ramp down mode.
    if (fb.congestion_signal() == fb.est_queuing_delay_signal_ms() &&
        fb.est_queuing_delay_signal_ms() < kQueuingDelayUpperBoundMs &&
        fb.exp_smoothed_delay_ms() <
            kMinNadaBitrateKbps / kProportionalityDelayBits &&
        fb.derivative() < kDerivativeUpperBound &&
        fb.receiving_rate() > kMinNadaBitrateKbps) {
      AcceleratedRampUp(fb);
    } else if (fb.congestion_signal() > kMaxCongestionSignalMs ||
               fb.exp_smoothed_delay_ms() > kMaxCongestionSignalMs) {
      AcceleratedRampDown(fb);
    } else {
      double bitrate_reference =
          (2.0 * bitrate_kbps_) / (kMaxBitrateKbps + kMinNadaBitrateKbps);
      double smoothing_factor = pow(bitrate_reference, 0.75);
      GradualRateUpdate(fb, delta_s, smoothing_factor);
    }
  }

  bitrate_kbps_ = std::min(bitrate_kbps_, kMaxBitrateKbps);
  bitrate_kbps_ = std::max(bitrate_kbps_, kMinNadaBitrateKbps);

  observer_->OnNetworkChanged(1000 * bitrate_kbps_, 0, rtt_ms);
}

int64_t NadaBweSender::TimeUntilNextProcess() {
  return 100;
}

void NadaBweSender::Process() {}

void NadaBweSender::AcceleratedRampUp(const NadaFeedback& fb) {
  const int kMaxRampUpQueuingDelayMs = 50;  // Referred as T_th.
  const float kGamma0 = 0.5f;               // Referred as gamma_0.

  float gamma =
      std::min(kGamma0, static_cast<float>(kMaxRampUpQueuingDelayMs) /
                            (min_round_trip_time_ms_ + min_feedback_delay_ms_));

  bitrate_kbps_ = static_cast<int>((1.0f + gamma) * fb.receiving_rate() + 0.5f);
}

void NadaBweSender::AcceleratedRampDown(const NadaFeedback& fb) {
  const float kGamma0 = 0.9f;
  float gamma = 3.0f * kMaxCongestionSignalMs /
                (fb.congestion_signal() + fb.exp_smoothed_delay_ms());
  gamma = std::min(gamma, kGamma0);
  bitrate_kbps_ = gamma * fb.receiving_rate() + 0.5f;
}

void NadaBweSender::GradualRateUpdate(const NadaFeedback& fb,
                                      float delta_s,
                                      double smoothing_factor) {
  const float kTauOMs = 500.0f;           // Referred as tau_o.
  const float kEta = 2.0f;                // Referred as eta.
  const float kKappa = 1.0f;              // Referred as kappa.
  const float kReferenceDelayMs = 10.0f;  // Referred as x_ref.
  const float kPriorityWeight = 1.0f;     // Referred as w.

  float x_hat = fb.congestion_signal() + kEta * kTauOMs * fb.derivative();

  float kTheta = kPriorityWeight * (kMaxBitrateKbps - kMinNadaBitrateKbps) *
                 kReferenceDelayMs;

  int original_increase = static_cast<int>(
      (kKappa * delta_s *
       (kTheta - (bitrate_kbps_ - kMinNadaBitrateKbps) * x_hat)) /
          (kTauOMs * kTauOMs) +
      0.5f);

  bitrate_kbps_ = bitrate_kbps_ + smoothing_factor * original_increase;
}

}  // namespace bwe
}  // namespace testing
}  // namespace webrtc
