// Copyright (c) 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 "quiche/quic/core/quic_mtu_discovery.h"

#include "quiche/quic/platform/api/quic_flag_utils.h"
#include "quiche/quic/platform/api/quic_stack_trace.h"

namespace quic {

QuicConnectionMtuDiscoverer::QuicConnectionMtuDiscoverer(
    QuicPacketCount packets_between_probes_base, QuicPacketNumber next_probe_at)
    : packets_between_probes_(packets_between_probes_base),
      next_probe_at_(next_probe_at) {}

void QuicConnectionMtuDiscoverer::Enable(
    QuicByteCount max_packet_length, QuicByteCount target_max_packet_length) {
  QUICHE_DCHECK(!IsEnabled());

  if (target_max_packet_length <= max_packet_length) {
    QUIC_DVLOG(1) << "MtuDiscoverer not enabled. target_max_packet_length:"
                  << target_max_packet_length
                  << " <= max_packet_length:" << max_packet_length;
    return;
  }

  min_probe_length_ = max_packet_length;
  max_probe_length_ = target_max_packet_length;
  QUICHE_DCHECK(IsEnabled());

  QUIC_DVLOG(1) << "MtuDiscoverer enabled. min:" << min_probe_length_
                << ", max:" << max_probe_length_
                << ", next:" << next_probe_packet_length();
}

void QuicConnectionMtuDiscoverer::Disable() {
  *this = QuicConnectionMtuDiscoverer(packets_between_probes_, next_probe_at_);
}

bool QuicConnectionMtuDiscoverer::IsEnabled() const {
  return min_probe_length_ < max_probe_length_;
}

bool QuicConnectionMtuDiscoverer::ShouldProbeMtu(
    QuicPacketNumber largest_sent_packet) const {
  if (!IsEnabled()) {
    return false;
  }

  if (remaining_probe_count_ == 0) {
    QUIC_DVLOG(1)
        << "ShouldProbeMtu returns false because max probe count reached";
    return false;
  }

  if (largest_sent_packet < next_probe_at_) {
    QUIC_DVLOG(1) << "ShouldProbeMtu returns false because not enough packets "
                     "sent since last probe. largest_sent_packet:"
                  << largest_sent_packet
                  << ", next_probe_at_:" << next_probe_at_;
    return false;
  }

  QUIC_DVLOG(1) << "ShouldProbeMtu returns true. largest_sent_packet:"
                << largest_sent_packet;
  return true;
}

QuicPacketLength QuicConnectionMtuDiscoverer::GetUpdatedMtuProbeSize(
    QuicPacketNumber largest_sent_packet) {
  QUICHE_DCHECK(ShouldProbeMtu(largest_sent_packet));

  QuicPacketLength probe_packet_length = next_probe_packet_length();
  if (probe_packet_length == last_probe_length_) {
    // The next probe packet is as big as the previous one. Assuming the
    // previous one exceeded MTU, we need to decrease the probe packet length.
    max_probe_length_ = probe_packet_length;
  } else {
    QUICHE_DCHECK_GT(probe_packet_length, last_probe_length_);
  }
  last_probe_length_ = next_probe_packet_length();

  packets_between_probes_ *= 2;
  next_probe_at_ = largest_sent_packet + packets_between_probes_ + 1;
  if (remaining_probe_count_ > 0) {
    --remaining_probe_count_;
  }

  QUIC_DVLOG(1) << "GetUpdatedMtuProbeSize: probe_packet_length:"
                << last_probe_length_
                << ", New packets_between_probes_:" << packets_between_probes_
                << ", next_probe_at_:" << next_probe_at_
                << ", remaining_probe_count_:" << remaining_probe_count_;
  QUICHE_DCHECK(!ShouldProbeMtu(largest_sent_packet));
  return last_probe_length_;
}

QuicPacketLength QuicConnectionMtuDiscoverer::next_probe_packet_length() const {
  QUICHE_DCHECK_NE(min_probe_length_, 0);
  QUICHE_DCHECK_NE(max_probe_length_, 0);
  QUICHE_DCHECK_GE(max_probe_length_, min_probe_length_);

  const QuicPacketLength normal_next_probe_length =
      (min_probe_length_ + max_probe_length_ + 1) / 2;

  if (remaining_probe_count_ == 1 &&
      normal_next_probe_length > last_probe_length_) {
    // If the previous probe succeeded, and there is only one last probe to
    // send, use |max_probe_length_| for the last probe.
    return max_probe_length_;
  }
  return normal_next_probe_length;
}

void QuicConnectionMtuDiscoverer::OnMaxPacketLengthUpdated(
    QuicByteCount old_value, QuicByteCount new_value) {
  if (!IsEnabled() || new_value <= old_value) {
    return;
  }

  QUICHE_DCHECK_EQ(old_value, min_probe_length_);
  min_probe_length_ = new_value;
}

std::ostream& operator<<(std::ostream& os,
                         const QuicConnectionMtuDiscoverer& d) {
  os << "{ min_probe_length_:" << d.min_probe_length_
     << " max_probe_length_:" << d.max_probe_length_
     << " last_probe_length_:" << d.last_probe_length_
     << " remaining_probe_count_:" << d.remaining_probe_count_
     << " packets_between_probes_:" << d.packets_between_probes_
     << " next_probe_at_:" << d.next_probe_at_ << " }";
  return os;
}

}  // namespace quic
