// 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 "quic/core/quic_coalesced_packet.h"

#include "absl/strings/str_cat.h"
#include "quic/platform/api/quic_bug_tracker.h"
#include "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_) {
      QUICHE_DCHECK(buffer.empty());
    }
#endif
    QUICHE_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_BUG << "Max packet length changes in the middle of the write path";
      return false;
    }
    if (ContainsPacketOfEncryptionLevel(packet.encryption_level)) {
      // Do not coalesce packets of the same encryption level.
      return false;
    }
  }

  if (length_ + packet.encrypted_length > max_packet_length_) {
    // Packet does not fit.
    return false;
  }
  QUIC_DVLOG(1) << "Successfully coalesced packet: encryption_level: "
                << packet.encryption_level
                << ", encrypted_length: " << packet.encrypted_length
                << ", current length: " << length_
                << ", max_packet_length: " << max_packet_length_;
  if (length_ > 0) {
    QUIC_CODE_COUNT(QUIC_SUCCESSFULLY_COALESCED_MULTIPLE_PACKETS);
  }
  length_ += packet.encrypted_length;
  transmission_types_[packet.encryption_level] = packet.transmission_type;
  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();
  }
  for (size_t i = ENCRYPTION_INITIAL; i < NUM_ENCRYPTION_LEVELS; ++i) {
    transmission_types_[i] = NOT_RETRANSMISSION;
  }
  initial_packet_ = nullptr;
}

void QuicCoalescedPacket::NeuterInitialPacket() {
  if (initial_packet_ == nullptr) {
    return;
  }
  if (length_ < initial_packet_->encrypted_length) {
    QUIC_BUG << "length_: " << length_
             << ", is less than initial packet length: "
             << initial_packet_->encrypted_length;
    Clear();
    return;
  }
  length_ -= initial_packet_->encrypted_length;
  if (length_ == 0) {
    Clear();
    return;
  }
  transmission_types_[ENCRYPTION_INITIAL] = NOT_RETRANSMISSION;
  initial_packet_ = nullptr;
}

bool QuicCoalescedPacket::CopyEncryptedBuffers(char* buffer,
                                               size_t buffer_len,
                                               size_t* length_copied) const {
  *length_copied = 0;
  for (const auto& packet : encrypted_buffers_) {
    if (packet.empty()) {
      continue;
    }
    if (packet.length() > buffer_len) {
      return false;
    }
    memcpy(buffer, packet.data(), packet.length());
    buffer += packet.length();
    buffer_len -= packet.length();
    *length_copied += packet.length();
  }
  return true;
}

bool QuicCoalescedPacket::ContainsPacketOfEncryptionLevel(
    EncryptionLevel level) const {
  return !encrypted_buffers_[level].empty() ||
         (level == ENCRYPTION_INITIAL && initial_packet_ != nullptr);
}

TransmissionType QuicCoalescedPacket::TransmissionTypeOfPacket(
    EncryptionLevel level) const {
  if (!ContainsPacketOfEncryptionLevel(level)) {
    QUIC_BUG << "Coalesced packet does not contain packet of encryption level: "
             << EncryptionLevelToString(level);
    return NOT_RETRANSMISSION;
  }
  return transmission_types_[level];
}

std::string QuicCoalescedPacket::ToString(size_t serialized_length) const {
  // Total length and padding size.
  std::string info = absl::StrCat(
      "total_length: ", serialized_length,
      " padding_size: ", serialized_length - length_, " packets: {");
  // Packets' encryption levels.
  bool first_packet = true;
  for (int8_t i = ENCRYPTION_INITIAL; i < NUM_ENCRYPTION_LEVELS; ++i) {
    if (ContainsPacketOfEncryptionLevel(static_cast<EncryptionLevel>(i))) {
      absl::StrAppend(&info, first_packet ? "" : ", ",
                      EncryptionLevelToString(static_cast<EncryptionLevel>(i)));
      first_packet = false;
    }
  }
  absl::StrAppend(&info, "}");
  return info;
}

}  // namespace quic
