// 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 "net/third_party/quiche/src/quic/core/quic_mtu_discovery.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_flag_utils.h"
#include "net/third_party/quiche/src/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) {
  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;
  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) {
  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;
    QUIC_RELOADABLE_FLAG_COUNT_N(quic_mtu_discovery_v2, 1, 3);
  } else {
    DCHECK_GT(probe_packet_length, last_probe_length_);
    QUIC_RELOADABLE_FLAG_COUNT_N(quic_mtu_discovery_v2, 2, 3);
  }
  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_;
  DCHECK(!ShouldProbeMtu(largest_sent_packet));
  return last_probe_length_;
}

QuicPacketLength QuicConnectionMtuDiscoverer::next_probe_packet_length() const {
  DCHECK_NE(min_probe_length_, 0);
  DCHECK_NE(max_probe_length_, 0);
  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;
  }

  DCHECK_EQ(old_value, min_probe_length_);
  min_probe_length_ = new_value;
  QUIC_RELOADABLE_FLAG_COUNT_N(quic_mtu_discovery_v2, 3, 3);
}

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
