/*
 *  Copyright (c) 2019 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/goog_cc/robust_throughput_estimator.h"

#include <stddef.h>

#include <algorithm>
#include <utility>

#include "rtc_base/checks.h"

namespace webrtc {

RobustThroughputEstimator::RobustThroughputEstimator(
    const RobustThroughputEstimatorSettings& settings)
    : settings_(settings) {
  RTC_DCHECK(settings.enabled);
}

RobustThroughputEstimator::~RobustThroughputEstimator() {}

void RobustThroughputEstimator::IncomingPacketFeedbackVector(
    const std::vector<PacketResult>& packet_feedback_vector) {
  RTC_DCHECK(std::is_sorted(packet_feedback_vector.begin(),
                            packet_feedback_vector.end(),
                            PacketResult::ReceiveTimeOrder()));
  for (const auto& packet : packet_feedback_vector) {
    // Insert the new packet.
    window_.push_back(packet);
    // In most cases, receive timestamps should already be in order, but in the
    // rare case where feedback packets have been reordered, we do some swaps to
    // ensure that the window is sorted.
    for (size_t i = window_.size() - 1;
         i > 0 && window_[i].receive_time < window_[i - 1].receive_time; i--) {
      std::swap(window_[i], window_[i - 1]);
    }
    // Remove old packets.
    while (window_.size() > settings_.kMaxPackets ||
           (window_.size() > settings_.min_packets &&
            packet.receive_time - window_.front().receive_time >
                settings_.window_duration)) {
      window_.pop_front();
    }
  }
}

absl::optional<DataRate> RobustThroughputEstimator::bitrate() const {
  if (window_.size() < settings_.initial_packets)
    return absl::nullopt;

  TimeDelta largest_recv_gap(TimeDelta::ms(0));
  TimeDelta second_largest_recv_gap(TimeDelta::ms(0));
  for (size_t i = 1; i < window_.size(); i++) {
    // Find receive time gaps
    TimeDelta gap = window_[i].receive_time - window_[i - 1].receive_time;
    if (gap > largest_recv_gap) {
      second_largest_recv_gap = largest_recv_gap;
      largest_recv_gap = gap;
    } else if (gap > second_largest_recv_gap) {
      second_largest_recv_gap = gap;
    }
  }

  Timestamp min_send_time = window_[0].sent_packet.send_time;
  Timestamp max_send_time = window_[0].sent_packet.send_time;
  Timestamp min_recv_time = window_[0].receive_time;
  Timestamp max_recv_time = window_[0].receive_time;
  DataSize data_size = DataSize::bytes(0);
  for (const auto& packet : window_) {
    min_send_time = std::min(min_send_time, packet.sent_packet.send_time);
    max_send_time = std::max(max_send_time, packet.sent_packet.send_time);
    min_recv_time = std::min(min_recv_time, packet.receive_time);
    max_recv_time = std::max(max_recv_time, packet.receive_time);
    data_size += packet.sent_packet.size;
    data_size +=
        packet.sent_packet.prior_unacked_data * settings_.unacked_weight;
  }

  // Suppose a packet of size S is sent every T milliseconds.
  // A window of N packets would contain N*S bytes, but the time difference
  // between the first and the last packet would only be (N-1)*T. Thus, we
  // need to remove one packet.
  DataSize recv_size = data_size;
  DataSize send_size = data_size;
  if (settings_.assume_shared_link) {
    // Depending on how the bottleneck queue is implemented, a large packet
    // may delay sending of sebsequent packets, so the delay between packets
    // i and i+1  depends on the size of both packets. In this case we minimize
    // the maximum error by removing half of both the first and last packet
    // size.
    DataSize first_last_average_size =
        (window_.front().sent_packet.size +
         window_.front().sent_packet.prior_unacked_data +
         window_.back().sent_packet.size +
         window_.back().sent_packet.prior_unacked_data) /
        2;
    recv_size -= first_last_average_size;
    send_size -= first_last_average_size;
  } else {
    // In the simpler case where the delay between packets i and i+1 only
    // depends on the size of packet i+1, the first packet doesn't give us
    // any information. Analogously, we assume that the start send time
    // for the last packet doesn't depend on the size of the packet.
    recv_size -= (window_.front().sent_packet.size +
                  window_.front().sent_packet.prior_unacked_data);
    send_size -= (window_.back().sent_packet.size +
                  window_.back().sent_packet.prior_unacked_data);
  }

  // Remove the largest gap by replacing it by the second largest gap
  // or the average gap.
  TimeDelta send_duration = max_send_time - min_send_time;
  TimeDelta recv_duration = (max_recv_time - min_recv_time) - largest_recv_gap;
  if (settings_.reduce_bias) {
    recv_duration += second_largest_recv_gap;
  } else {
    recv_duration += recv_duration / (window_.size() - 2);
  }

  send_duration = std::max(send_duration, TimeDelta::ms(1));
  recv_duration = std::max(recv_duration, TimeDelta::ms(1));
  return std::min(send_size / send_duration, recv_size / recv_duration);
}

}  // namespace webrtc
