/*
 *  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/monitor_interval.h"
#include "rtc_base/logging.h"

namespace webrtc {
namespace pcc {

PccMonitorInterval::PccMonitorInterval(DataRate target_sending_rate,
                                       Timestamp start_time,
                                       TimeDelta duration)
    : target_sending_rate_(target_sending_rate),
      start_time_(start_time),
      interval_duration_(duration),
      received_packets_size_(DataSize::Zero()),
      feedback_collection_done_(false) {}

PccMonitorInterval::~PccMonitorInterval() = default;

PccMonitorInterval::PccMonitorInterval(const PccMonitorInterval& other) =
    default;

void PccMonitorInterval::OnPacketsFeedback(
    const std::vector<PacketResult>& packets_results) {
  for (const PacketResult& packet_result : packets_results) {
    if (!packet_result.sent_packet.has_value() ||
        packet_result.sent_packet->send_time <= start_time_) {
      continue;
    }
    // Here we assume that if some packets are reordered with packets sent
    // after the end of the monitor interval, then they are lost. (Otherwise
    // it is not clear how long should we wait for packets feedback to arrive).
    if (packet_result.sent_packet->send_time >
        start_time_ + interval_duration_) {
      feedback_collection_done_ = true;
      return;
    }
    if (packet_result.receive_time.IsInfinite()) {
      lost_packets_sent_time_.push_back(packet_result.sent_packet->send_time);
    } else {
      received_packets_.push_back(
          {packet_result.receive_time - packet_result.sent_packet->send_time,
           packet_result.sent_packet->send_time});
      received_packets_size_ += packet_result.sent_packet->size;
    }
  }
}

// For the formula used in computations see formula for "slope" in the second
// method:
// https://www.johndcook.com/blog/2008/10/20/comparing-two-ways-to-fit-a-line-to-data/
double PccMonitorInterval::ComputeDelayGradient(
    double delay_gradient_threshold) const {
  // Early return to prevent division by 0 in case all packets are sent at the
  // same time.
  if (received_packets_.empty() || received_packets_.front().sent_time ==
                                       received_packets_.back().sent_time) {
    return 0;
  }
  double sum_times = 0;
  double sum_delays = 0;
  for (const ReceivedPacket& packet : received_packets_) {
    double time_delta_us =
        (packet.sent_time - received_packets_[0].sent_time).us();
    double delay = packet.delay.us();
    sum_times += time_delta_us;
    sum_delays += delay;
  }
  double sum_squared_scaled_time_deltas = 0;
  double sum_scaled_time_delta_dot_delay = 0;
  for (const ReceivedPacket& packet : received_packets_) {
    double time_delta_us =
        (packet.sent_time - received_packets_[0].sent_time).us();
    double delay = packet.delay.us();
    double scaled_time_delta_us =
        time_delta_us - sum_times / received_packets_.size();
    sum_squared_scaled_time_deltas +=
        scaled_time_delta_us * scaled_time_delta_us;
    sum_scaled_time_delta_dot_delay += scaled_time_delta_us * delay;
  }
  double rtt_gradient =
      sum_scaled_time_delta_dot_delay / sum_squared_scaled_time_deltas;
  if (std::abs(rtt_gradient) < delay_gradient_threshold)
    rtt_gradient = 0;
  return rtt_gradient;
}

bool PccMonitorInterval::IsFeedbackCollectionDone() const {
  return feedback_collection_done_;
}

Timestamp PccMonitorInterval::GetEndTime() const {
  return start_time_ + interval_duration_;
}

double PccMonitorInterval::GetLossRate() const {
  size_t packets_lost = lost_packets_sent_time_.size();
  size_t packets_received = received_packets_.size();
  if (packets_lost == 0)
    return 0;
  return static_cast<double>(packets_lost) / (packets_lost + packets_received);
}

DataRate PccMonitorInterval::GetTargetSendingRate() const {
  return target_sending_rate_;
}

DataRate PccMonitorInterval::GetTransmittedPacketsRate() const {
  if (received_packets_.empty()) {
    return target_sending_rate_;
  }
  Timestamp receive_time_of_first_packet =
      received_packets_.front().sent_time + received_packets_.front().delay;
  Timestamp receive_time_of_last_packet =
      received_packets_.back().sent_time + received_packets_.back().delay;
  if (receive_time_of_first_packet == receive_time_of_last_packet) {
    RTC_LOG(LS_WARNING)
        << "All packets in monitor interval were received at the same time.";
    return target_sending_rate_;
  }
  return received_packets_size_ /
         (receive_time_of_last_packet - receive_time_of_first_packet);
}

}  // namespace pcc
}  // namespace webrtc
