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

#include "absl/memory/memory.h"
#include "absl/strings/str_cat.h"
#include "quiche/quic/platform/api/quic_bug_tracker.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,
    quiche::QuicheBufferAllocator* allocator,
    QuicPacketLength current_max_packet_length) {
  if (packet.encrypted_length == 0) {
    QUIC_BUG(quic_bug_10611_1) << "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(quic_bug_10611_2)
          << "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_ = absl::WrapUnique<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(quic_bug_10611_3)
        << "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(quic_bug_10611_4)
        << "Coalesced packet does not contain packet of encryption level: "
        << EncryptionLevelToString(level);
    return NOT_RETRANSMISSION;
  }
  return transmission_types_[level];
}

size_t QuicCoalescedPacket::NumberOfPackets() const {
  size_t num_of_packets = 0;
  for (int8_t i = ENCRYPTION_INITIAL; i < NUM_ENCRYPTION_LEVELS; ++i) {
    if (ContainsPacketOfEncryptionLevel(static_cast<EncryptionLevel>(i))) {
      ++num_of_packets;
    }
  }
  return num_of_packets;
}

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;
}

std::vector<size_t> QuicCoalescedPacket::packet_lengths() const {
  std::vector<size_t> lengths;
  for (const auto& packet : encrypted_buffers_) {
    if (lengths.empty()) {
      lengths.push_back(
          initial_packet_ == nullptr ? 0 : initial_packet_->encrypted_length);
    } else {
      lengths.push_back(packet.length());
    }
  }
  return lengths;
}

}  // namespace quic
