/*
 *  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 <stddef.h>

#include <cmath>

#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.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.IsReceived()) {
      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
