// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/third_party/quic/core/congestion_control/uber_loss_algorithm.h"

#include <algorithm>

namespace quic {

UberLossAlgorithm::UberLossAlgorithm() : UberLossAlgorithm(kNack) {}

UberLossAlgorithm::UberLossAlgorithm(LossDetectionType loss_type)
    : loss_type_(loss_type) {
  SetLossDetectionType(loss_type);
  for (int8_t i = INITIAL_DATA; i < NUM_PACKET_NUMBER_SPACES; ++i) {
    general_loss_algorithms_[i].SetPacketNumberSpace(
        static_cast<PacketNumberSpace>(i));
  }
}

LossDetectionType UberLossAlgorithm::GetLossDetectionType() const {
  return loss_type_;
}

void UberLossAlgorithm::SetLossDetectionType(LossDetectionType loss_type) {
  loss_type_ = loss_type;
  for (auto& loss_algorithm : general_loss_algorithms_) {
    loss_algorithm.SetLossDetectionType(loss_type);
  }
}

void UberLossAlgorithm::DetectLosses(
    const QuicUnackedPacketMap& unacked_packets,
    QuicTime time,
    const RttStats& rtt_stats,
    QuicPacketNumber /*largest_newly_acked*/,
    const AckedPacketVector& packets_acked,
    LostPacketVector* packets_lost) {
  DCHECK(unacked_packets.use_uber_loss_algorithm());
  for (int8_t i = INITIAL_DATA; i < NUM_PACKET_NUMBER_SPACES; ++i) {
    const QuicPacketNumber largest_acked =
        unacked_packets.GetLargestAckedOfPacketNumberSpace(
            static_cast<PacketNumberSpace>(i));
    if (!largest_acked.IsInitialized() ||
        unacked_packets.GetLeastUnacked() > largest_acked) {
      // Skip detecting losses if no packet has been received for this packet
      // number space or the least_unacked is greater than largest_acked.
      continue;
    }

    general_loss_algorithms_[i].DetectLosses(unacked_packets, time, rtt_stats,
                                             largest_acked, packets_acked,
                                             packets_lost);
  }
}

QuicTime UberLossAlgorithm::GetLossTimeout() const {
  QuicTime loss_timeout = QuicTime::Zero();
  // Returns the earliest non-zero loss timeout.
  for (int8_t i = INITIAL_DATA; i < NUM_PACKET_NUMBER_SPACES; ++i) {
    const QuicTime timeout = general_loss_algorithms_[i].GetLossTimeout();
    if (!loss_timeout.IsInitialized()) {
      loss_timeout = timeout;
      continue;
    }
    if (timeout.IsInitialized()) {
      loss_timeout = std::min(loss_timeout, timeout);
    }
  }
  return loss_timeout;
}

void UberLossAlgorithm::SpuriousRetransmitDetected(
    const QuicUnackedPacketMap& unacked_packets,
    QuicTime time,
    const RttStats& rtt_stats,
    QuicPacketNumber spurious_retransmission) {
  DCHECK(unacked_packets.use_uber_loss_algorithm());
  general_loss_algorithms_[unacked_packets.GetPacketNumberSpace(
                               spurious_retransmission)]
      .SpuriousRetransmitDetected(unacked_packets, time, rtt_stats,
                                  spurious_retransmission);
}

}  // namespace quic
