// 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_coalesced_packet.h"

#include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_ptr_util.h"

namespace quic {

QuicCoalescedPacket::QuicCoalescedPacket()
    : length_(0), max_packet_length_(0) {}

QuicCoalescedPacket::~QuicCoalescedPacket() {
  Clear();
}

bool QuicCoalescedPacket::MaybeCoalescePacket(
    const SerializedPacket& packet,
    const QuicSocketAddress& self_address,
    const QuicSocketAddress& peer_address,
    QuicBufferAllocator* allocator,
    QuicPacketLength current_max_packet_length) {
  if (packet.encrypted_length == 0) {
    QUIC_BUG << "Trying to coalesce an empty packet";
    return true;
  }
  if (length_ == 0) {
#ifndef NDEBUG
    for (const auto& buffer : encrypted_buffers_) {
      DCHECK(buffer.empty());
    }
#endif
    DCHECK(initial_packet_ == nullptr);
    // This is the first packet, set max_packet_length and self/peer
    // addresses.
    max_packet_length_ = current_max_packet_length;
    self_address_ = self_address;
    peer_address_ = peer_address;
  } else {
    if (self_address_ != self_address || peer_address_ != peer_address) {
      // Do not coalesce packet with different self/peer addresses.
      QUIC_DLOG(INFO)
          << "Cannot coalesce packet because self/peer address changed";
      return false;
    }
    if (max_packet_length_ != current_max_packet_length) {
      QUIC_DLOG(INFO)
          << "Do not try to coalesce packet when max packet length changed.";
      return false;
    }
    if (!encrypted_buffers_[packet.encryption_level].empty() ||
        (packet.encryption_level == ENCRYPTION_INITIAL &&
         initial_packet_ != nullptr)) {
      // Do not coalesce packets of the same encryption level.
      return false;
    }
  }

  if (packet.encryption_level == ENCRYPTION_INITIAL) {
    for (const auto& frame : packet.nonretransmittable_frames) {
      if (frame.type == PADDING_FRAME) {
        QUIC_BUG << "ENCRYPTION_INITIAL packet should not contain padding "
                    "frame if trying to send coalesced packet";
        return false;
      }
    }
  }
  if (length_ + packet.encrypted_length > max_packet_length_) {
    // Packet does not fit.
    return false;
  }

  length_ += packet.encrypted_length;
  if (packet.encryption_level == ENCRYPTION_INITIAL) {
    // Save a copy of ENCRYPTION_INITIAL packet (excluding encrypted buffer, as
    // the packet will be re-serialized later).
    initial_packet_ = QuicWrapUnique<SerializedPacket>(
        CopySerializedPacket(packet, allocator, /*copy_buffer=*/false));
    return true;
  }
  // Copy encrypted buffer of packets with other encryption levels.
  encrypted_buffers_[packet.encryption_level] =
      std::string(packet.encrypted_buffer, packet.encrypted_length);
  return true;
}

void QuicCoalescedPacket::Clear() {
  self_address_ = QuicSocketAddress();
  peer_address_ = QuicSocketAddress();
  length_ = 0;
  max_packet_length_ = 0;
  for (auto& packet : encrypted_buffers_) {
    packet.clear();
  }
  if (initial_packet_ != nullptr) {
    ClearSerializedPacket(initial_packet_.get());
  }
  initial_packet_ = nullptr;
}

}  // namespace quic
