/** @file
 *
 *  A brief file description
 *
 *  @section license License
 *
 *  Licensed to the Apache Software Foundation (ASF) under one
 *  or more contributor license agreements.  See the NOTICE file
 *  distributed with this work for additional information
 *  regarding copyright ownership.  The ASF licenses this file
 *  to you under the Apache License, Version 2.0 (the
 *  "License"); you may not use this file except in compliance
 *  with the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

#include "QUICFrame.h"

#include <algorithm>

#include "QUICStream.h"
#include "QUICIntUtil.h"
#include "QUICDebugNames.h"
#include "QUICPacket.h"

#define LEFT_SPACE(pos) ((size_t)(buf + len - pos))
#define FRAME_SIZE(pos) (pos - buf)

// the pos will auto move forward . return true if the data valid
static bool
read_varint(uint8_t *&pos, size_t len, uint64_t &field, size_t &field_len)
{
  if (len < 1) {
    return false;
  }

  field_len = QUICVariableInt::size(pos);
  if (len < field_len) {
    return false;
  }

  field = QUICIntUtil::read_QUICVariableInt(pos, len);
  pos += field_len;
  return true;
}

QUICFrameType
QUICFrame::type() const
{
  ink_assert("should not be called");
  return QUICFrameType::UNKNOWN;
}

bool
QUICFrame::ack_eliciting() const
{
  auto type = this->type();

  return type != QUICFrameType::PADDING && type != QUICFrameType::ACK && type != QUICFrameType::CONNECTION_CLOSE;
}

const QUICPacketR *
QUICFrame::packet() const
{
  return this->_packet;
}

bool
QUICFrame::is_probing_frame() const
{
  return false;
}

bool
QUICFrame::is_flow_controlled() const
{
  return false;
}

QUICFrameId
QUICFrame::id() const
{
  return this->_id;
}

QUICFrameGenerator *
QUICFrame::generated_by()
{
  return this->_owner;
}

QUICFrameType
QUICFrame::type(const uint8_t *buf)
{
  if (buf[0] >= static_cast<uint8_t>(QUICFrameType::UNKNOWN)) {
    return QUICFrameType::UNKNOWN;
  } else if (static_cast<uint8_t>(QUICFrameType::ACK) <= buf[0] && buf[0] < static_cast<uint8_t>(QUICFrameType::RESET_STREAM)) {
    return QUICFrameType::ACK;
  } else if (static_cast<uint8_t>(QUICFrameType::STREAM) <= buf[0] && buf[0] < static_cast<uint8_t>(QUICFrameType::MAX_DATA)) {
    return QUICFrameType::STREAM;
  } else if (static_cast<uint8_t>(QUICFrameType::MAX_STREAMS) <= buf[0] &&
             buf[0] < static_cast<uint8_t>(QUICFrameType::DATA_BLOCKED)) {
    return QUICFrameType::MAX_STREAMS;
  } else if (static_cast<uint8_t>(QUICFrameType::STREAMS_BLOCKED) <= buf[0] &&
             buf[0] < static_cast<uint8_t>(QUICFrameType::NEW_CONNECTION_ID)) {
    return QUICFrameType::STREAMS_BLOCKED;
  } else if (static_cast<uint8_t>(QUICFrameType::CONNECTION_CLOSE) <= buf[0] &&
             buf[0] < static_cast<uint8_t>(QUICFrameType::HANDSHAKE_DONE)) {
    return QUICFrameType::CONNECTION_CLOSE;
  } else {
    return static_cast<QUICFrameType>(buf[0]);
  }
}

int
QUICFrame::debug_msg(char *msg, size_t msg_len) const
{
  return snprintf(msg, msg_len, "%s size=%zu", QUICDebugNames::frame_type(this->type()), this->size());
}

bool
QUICFrame::valid() const
{
  return this->_valid;
}

//
// STREAM Frame
//

QUICStreamFrame::QUICStreamFrame(Ptr<IOBufferBlock> &block, QUICStreamId stream_id, QUICOffset offset, bool last,
                                 bool has_offset_field, bool has_length_field, QUICFrameId id, QUICFrameGenerator *owner)
  : QUICFrame(id, owner),
    _block(block),
    _stream_id(stream_id),
    _offset(offset),
    _fin(last),
    _has_offset_field(has_offset_field),
    _has_length_field(has_length_field)
{
}

QUICStreamFrame::QUICStreamFrame(const uint8_t *buf, size_t len, const QUICPacketR *packet) : QUICFrame(0, nullptr, packet)
{
  this->parse(buf, len, packet);
}

QUICStreamFrame::QUICStreamFrame(const QUICStreamFrame &o)
  : QUICFrame(o),
    _block(make_ptr<IOBufferBlock>(o._block->clone())),
    _stream_id(o._stream_id),
    _offset(o._offset),
    _fin(o._fin),
    _has_offset_field(o._has_offset_field),
    _has_length_field(o._has_length_field)
{
}

void
QUICStreamFrame::parse(const uint8_t *buf, size_t len, const QUICPacketR *packet)
{
  ink_assert(len >= 1);
  this->_reset();
  this->_packet = packet;

  uint8_t *pos            = const_cast<uint8_t *>(buf);
  this->_has_offset_field = (buf[0] & 0x04) != 0; // "O" of "0b00010OLF"
  this->_has_length_field = (buf[0] & 0x02) != 0; // "L" of "0b00010OLF"
  this->_fin              = (buf[0] & 0x01) != 0; // "F" of "0b00010OLF"
  pos += 1;

  size_t field_len = 0;
  if (!read_varint(pos, LEFT_SPACE(pos), this->_stream_id, field_len)) {
    return;
  }

  if (this->_has_offset_field && !read_varint(pos, LEFT_SPACE(pos), this->_offset, field_len)) {
    return;
  }

  uint64_t data_len = 0;
  if (this->_has_length_field && !read_varint(pos, LEFT_SPACE(pos), data_len, field_len)) {
    return;
  }

  if (!this->_has_length_field) {
    data_len = LEFT_SPACE(pos);
  }
  if (LEFT_SPACE(pos) < data_len) {
    return;
  }

  this->_valid = true;
  this->_block = make_ptr<IOBufferBlock>(new_IOBufferBlock());
  this->_block->alloc(BUFFER_SIZE_INDEX_32K);
  ink_assert(static_cast<uint64_t>(this->_block->write_avail()) > data_len);
  memcpy(this->_block->start(), pos, data_len);
  this->_block->fill(data_len);
  pos += data_len;
  this->_size = FRAME_SIZE(pos);
}

void
QUICStreamFrame::_reset()
{
  this->_block            = nullptr;
  this->_fin              = false;
  this->_has_length_field = true;
  this->_has_offset_field = true;
  this->_offset           = 0;
  this->_stream_id        = 0;
  this->_owner            = nullptr;
  this->_id               = 0;
  this->_valid            = false;
  this->_size             = 0;
}

QUICFrameType
QUICStreamFrame::type() const
{
  return QUICFrameType::STREAM;
}

size_t
QUICStreamFrame::size() const
{
  if (this->_size) {
    return this->_size;
  }

  size_t size     = 1;
  size_t data_len = 0;
  if (this->_block.get() != nullptr) {
    data_len = this->_block->read_avail();
  }

  size += QUICVariableInt::size(this->_stream_id);
  if (this->_has_offset_field) {
    size += QUICVariableInt::size(this->_offset);
  }

  if (this->_has_length_field) {
    size += QUICVariableInt::size(data_len);
    size += data_len;
  }

  return size;
}

bool
QUICStreamFrame::is_flow_controlled() const
{
  return true;
}

int
QUICStreamFrame::debug_msg(char *msg, size_t msg_len) const
{
  return snprintf(msg, msg_len, "STREAM size=%zu id=%" PRIu64 " offset=%" PRIu64 " data_len=%" PRIu64 " fin=%d", this->size(),
                  this->stream_id(), this->offset(), this->data_length(), this->has_fin_flag());
}

Ptr<IOBufferBlock>
QUICStreamFrame::to_io_buffer_block(size_t limit) const
{
  Ptr<IOBufferBlock> header;

  if (limit < this->size()) {
    return header;
  }

  // Create header block
  size_t written_len = 0;
  header             = make_ptr<IOBufferBlock>(new_IOBufferBlock());
  header->alloc(iobuffer_size_to_index(MAX_HEADER_SIZE, BUFFER_SIZE_INDEX_32K));
  this->_store_header(reinterpret_cast<uint8_t *>(header->start()), &written_len, true);
  header->fill(written_len);

  // Append payload block to a chain
  ink_assert(written_len + this->data_length() <= limit);
  header->next = this->data();

  // Return the chain
  return header;
}

size_t
QUICStreamFrame::_store_header(uint8_t *buf, size_t *len, bool include_length_field) const
{
  // Build Frame Type: "0b0010OLF"
  buf[0] = static_cast<uint8_t>(QUICFrameType::STREAM);
  *len   = 1;

  size_t n;

  // Stream ID (i)
  QUICTypeUtil::write_QUICStreamId(this->stream_id(), buf + *len, &n);
  *len += n;

  // [Offset (i)] "O" of "0b0010OLF"
  if (this->has_offset_field()) {
    QUICTypeUtil::write_QUICOffset(this->offset(), buf + *len, &n);
    *len += n;
    buf[0] += 0x04;
  }

  // [Length (i)] "L of "0b0010OLF"
  if (include_length_field) {
    QUICIntUtil::write_QUICVariableInt(this->data_length(), buf + *len, &n);
    *len += n;
    buf[0] += 0x02;
  }

  // "F" of "0b0010OLF"
  if (this->has_fin_flag()) {
    buf[0] += 0x01;
  }

  return *len;
}

QUICStreamId
QUICStreamFrame::stream_id() const
{
  return this->_stream_id;
}

QUICOffset
QUICStreamFrame::offset() const
{
  if (this->has_offset_field()) {
    return this->_offset;
  }

  return 0;
}

uint64_t
QUICStreamFrame::data_length() const
{
  return this->_block->read_avail();
}

IOBufferBlock *
QUICStreamFrame::data() const
{
  return this->_block.get();
}

/**
 * "O" of "0b00010OLF"
 */
bool
QUICStreamFrame::has_offset_field() const
{
  return this->_has_offset_field;
}

/**
 * "L" of "0b00010OLF"
 */
bool
QUICStreamFrame::has_length_field() const
{
  // This depends on `include_length_field` arg of QUICStreamFrame::store.
  // Returning true for just in case.
  return this->_has_length_field;
}

/**
 * "F" of "0b00010OLF"
 */
bool
QUICStreamFrame::has_fin_flag() const
{
  return this->_fin;
}

//
// CRYPTO frame
//

QUICCryptoFrame::QUICCryptoFrame(Ptr<IOBufferBlock> &block, QUICOffset offset, QUICFrameId id, QUICFrameGenerator *owner)
  : QUICFrame(id, owner), _offset(offset), _block(block)
{
}

QUICCryptoFrame::QUICCryptoFrame(const uint8_t *buf, size_t len, const QUICPacketR *packet) : QUICFrame(0, nullptr, packet)
{
  this->parse(buf, len, packet);
}

QUICCryptoFrame::QUICCryptoFrame(const QUICCryptoFrame &o)
  : QUICFrame(o), _offset(o._offset), _block(make_ptr<IOBufferBlock>(o._block->clone()))
{
}

void
QUICCryptoFrame::parse(const uint8_t *buf, size_t len, const QUICPacketR *packet)
{
  ink_assert(len >= 1);
  this->_reset();
  this->_packet = packet;
  uint8_t *pos  = const_cast<uint8_t *>(buf) + 1;

  size_t field_len = 0;
  if (!read_varint(pos, LEFT_SPACE(pos), this->_offset, field_len)) {
    return;
  }

  uint64_t data_len = 0;
  if (!read_varint(pos, LEFT_SPACE(pos), data_len, field_len)) {
    return;
  }

  if (LEFT_SPACE(pos) < data_len) {
    return;
  }

  this->_valid = true;
  this->_block = make_ptr<IOBufferBlock>(new_IOBufferBlock());
  this->_block->alloc(BUFFER_SIZE_INDEX_32K);
  ink_assert(static_cast<uint64_t>(this->_block->write_avail()) > data_len);
  memcpy(this->_block->start(), pos, data_len);
  this->_block->fill(data_len);
  pos += data_len;
  this->_size = FRAME_SIZE(pos);
}

void
QUICCryptoFrame::_reset()
{
  this->_block  = nullptr;
  this->_offset = 0;
  this->_owner  = nullptr;
  this->_id     = 0;
  this->_valid  = false;
  this->_size   = 0;
}

// QUICFrame *
// QUICCryptoFrame::clone(uint8_t *buf) const
// {
//   Ptr<IOBufferBlock> block = make_ptr<IOBufferBlock>(this->_block->clone());
//   return QUICFrameFactory::create_crypto_frame(buf, block, this->offset(), this->_id, this->_owner);
// }

QUICFrameType
QUICCryptoFrame::type() const
{
  return QUICFrameType::CRYPTO;
}

size_t
QUICCryptoFrame::size() const
{
  if (this->_size) {
    return this->_size;
  }

  return 1 + this->_block->read_avail() + QUICVariableInt::size(this->_offset) + QUICVariableInt::size(this->_block->read_avail());
}

int
QUICCryptoFrame::debug_msg(char *msg, size_t msg_len) const
{
  return snprintf(msg, msg_len, "CRYPTO size=%zu offset=%" PRIu64 " data_len=%" PRIu64, this->size(), this->offset(),
                  this->data_length());
}

Ptr<IOBufferBlock>
QUICCryptoFrame::to_io_buffer_block(size_t limit) const
{
  Ptr<IOBufferBlock> header;

  if (limit < this->size()) {
    return header;
  }

  // Create header block
  size_t written_len = 0;
  header             = make_ptr<IOBufferBlock>(new_IOBufferBlock());
  header->alloc(iobuffer_size_to_index(MAX_HEADER_SIZE, BUFFER_SIZE_INDEX_32K));
  this->_store_header(reinterpret_cast<uint8_t *>(header->start()), &written_len);
  header->fill(written_len);

  // Append payload block to a chain
  ink_assert(written_len + this->data_length() <= limit);
  header->next = this->data();

  // Return the chain
  return header;
}

size_t
QUICCryptoFrame::_store_header(uint8_t *buf, size_t *len) const
{
  // Type
  buf[0] = static_cast<uint8_t>(QUICFrameType::CRYPTO);
  *len   = 1;

  size_t n;

  // Offset (i)
  QUICTypeUtil::write_QUICOffset(this->offset(), buf + *len, &n);
  *len += n;

  // Length (i)
  QUICIntUtil::write_QUICVariableInt(this->data_length(), buf + *len, &n);
  *len += n;

  return *len;
}

QUICOffset
QUICCryptoFrame::offset() const
{
  return this->_offset;
}

uint64_t
QUICCryptoFrame::data_length() const
{
  return this->_block->read_avail();
}

IOBufferBlock *
QUICCryptoFrame::data() const
{
  return this->_block.get();
}

//
// ACK frame
//

std::set<QUICAckFrame::PacketNumberRange>
QUICAckFrame::ranges() const
{
  std::set<QUICAckFrame::PacketNumberRange> numbers;
  QUICPacketNumber x = this->largest_acknowledged();
  numbers.insert({x, static_cast<uint64_t>(x) - this->ack_block_section()->first_ack_block()});
  x -= this->ack_block_section()->first_ack_block() + 1;
  for (auto &&block : *(this->ack_block_section())) {
    x -= block.gap() + 1;
    numbers.insert({x, static_cast<uint64_t>(x) - block.length()});
    x -= block.length() + 1;
  }

  return numbers;
}

QUICAckFrame::QUICAckFrame(const uint8_t *buf, size_t len, const QUICPacketR *packet) : QUICFrame(0, nullptr, packet)
{
  this->parse(buf, len, packet);
}

void
QUICAckFrame::parse(const uint8_t *buf, size_t len, const QUICPacketR *packet)
{
  ink_assert(len >= 1);
  this->_reset();
  this->_packet = packet;
  uint8_t *pos  = const_cast<uint8_t *>(buf) + 1;
  bool has_ecn  = (buf[0] == static_cast<uint8_t>(QUICFrameType::ACK_WITH_ECN));

  size_t field_len = 0;
  if (!read_varint(pos, LEFT_SPACE(pos), this->_largest_acknowledged, field_len)) {
    return;
  }

  if (!read_varint(pos, LEFT_SPACE(pos), this->_ack_delay, field_len)) {
    return;
  }

  uint64_t ack_block_count = 0;
  if (!read_varint(pos, LEFT_SPACE(pos), ack_block_count, field_len)) {
    return;
  }

  uint64_t first_ack_block = 0;
  if (!read_varint(pos, LEFT_SPACE(pos), first_ack_block, field_len)) {
    return;
  }

  this->_ack_block_section = new AckBlockSection(first_ack_block);
  for (size_t i = 0; i < ack_block_count; i++) {
    uint64_t gap           = 0;
    uint64_t add_ack_block = 0;

    if (!read_varint(pos, LEFT_SPACE(pos), gap, field_len)) {
      return;
    }

    if (!read_varint(pos, LEFT_SPACE(pos), add_ack_block, field_len)) {
      return;
    }

    this->_ack_block_section->add_ack_block({gap, add_ack_block});
  }

  if (has_ecn) {
    this->_ecn_section = new EcnSection(pos, LEFT_SPACE(pos));
    if (!this->_ecn_section->valid()) {
      return;
    }
    pos += this->_ecn_section->size();
  }

  this->_valid = true;
  this->_size  = FRAME_SIZE(pos);
}

QUICAckFrame::QUICAckFrame(QUICPacketNumber largest_acknowledged, uint64_t ack_delay, uint64_t first_ack_block, QUICFrameId id,
                           QUICFrameGenerator *owner)
  : QUICFrame(id, owner)
{
  this->_largest_acknowledged = largest_acknowledged;
  this->_ack_delay            = ack_delay;
  this->_ack_block_section    = new AckBlockSection(first_ack_block);
}

void
QUICAckFrame::_reset()
{
  if (this->_ack_block_section) {
    delete this->_ack_block_section;
    this->_ack_block_section = nullptr;
  }
  if (this->_ecn_section) {
    delete this->_ecn_section;
    this->_ecn_section = nullptr;
  }

  this->_largest_acknowledged = 0;
  this->_ack_delay            = 0;
  this->_owner                = nullptr;
  this->_id                   = 0;
  this->_valid                = false;
  this->_size                 = 0;
}

QUICAckFrame::~QUICAckFrame()
{
  if (this->_ack_block_section) {
    delete this->_ack_block_section;
    this->_ack_block_section = nullptr;
  }
  if (this->_ecn_section) {
    delete this->_ecn_section;
    this->_ecn_section = nullptr;
  }
}

QUICFrameType
QUICAckFrame::type() const
{
  // TODO ECN
  return QUICFrameType::ACK;
}

size_t
QUICAckFrame::size() const
{
  if (this->_size) {
    return this->_size;
  }

  size_t pre_len = 1 + QUICVariableInt::size(this->_largest_acknowledged) + QUICVariableInt::size(this->_ack_delay) +
                   QUICVariableInt::size(this->_ack_block_section->count());
  if (this->_ack_block_section) {
    pre_len += this->_ack_block_section->size();
  }

  if (this->_ecn_section) {
    return pre_len + this->_ecn_section->size();
  }

  return pre_len;
}

Ptr<IOBufferBlock>
QUICAckFrame::to_io_buffer_block(size_t limit) const
{
  Ptr<IOBufferBlock> block;
  size_t n = 0;

  if (limit < this->size()) {
    return block;
  }

  size_t written_len = 0;
  block              = make_ptr<IOBufferBlock>(new_IOBufferBlock());
  block->alloc(iobuffer_size_to_index(1 + 24, BUFFER_SIZE_INDEX_32K));
  uint8_t *block_start = reinterpret_cast<uint8_t *>(block->start());

  // Type
  block_start[0] = static_cast<uint8_t>(QUICFrameType::ACK);
  n += 1;

  // Largest Acknowledged (i)
  QUICIntUtil::write_QUICVariableInt(this->_largest_acknowledged, block_start + n, &written_len);
  n += written_len;

  // Ack Delay (i)
  QUICIntUtil::write_QUICVariableInt(this->_ack_delay, block_start + n, &written_len);
  n += written_len;

  // Ack Range Count (i)
  QUICIntUtil::write_QUICVariableInt(this->ack_block_count(), block_start + n, &written_len);
  n += written_len;

  block->fill(n);

  // First Ack Range (i) + Ack Ranges (*)
  block->next = this->_ack_block_section->to_io_buffer_block(limit - n);

  return block;
}

int
QUICAckFrame::debug_msg(char *msg, size_t msg_len) const
{
  int len = snprintf(msg, msg_len, "ACK size=%zu largest_acked=%" PRIu64 " delay=%" PRIu64 " block_count=%" PRIu64, this->size(),
                     this->largest_acknowledged(), this->ack_delay(), this->ack_block_count());
  msg_len -= len;

  if (this->ack_block_section()) {
    len += snprintf(msg + len, msg_len, " first_ack_block=%" PRIu64, this->ack_block_section()->first_ack_block());
  }

  return len;
}

QUICPacketNumber
QUICAckFrame::largest_acknowledged() const
{
  return this->_largest_acknowledged;
}

uint64_t
QUICAckFrame::ack_delay() const
{
  return this->_ack_delay;
}

uint64_t
QUICAckFrame::ack_block_count() const
{
  return this->_ack_block_section->count();
}

QUICAckFrame::AckBlockSection *
QUICAckFrame::ack_block_section()
{
  return this->_ack_block_section;
}

const QUICAckFrame::AckBlockSection *
QUICAckFrame::ack_block_section() const
{
  return this->_ack_block_section;
}

QUICAckFrame::EcnSection *
QUICAckFrame::ecn_section()
{
  return this->_ecn_section;
}

const QUICAckFrame::EcnSection *
QUICAckFrame::ecn_section() const
{
  return this->_ecn_section;
}

//
// QUICAckFrame::PacketNumberRange
//
QUICAckFrame::PacketNumberRange::PacketNumberRange(PacketNumberRange &&a) noexcept
{
  this->_first = a._first;
  this->_last  = a._last;
}

uint64_t
QUICAckFrame::PacketNumberRange::first() const
{
  return this->_first;
}

uint64_t
QUICAckFrame::PacketNumberRange::last() const
{
  return this->_last;
}

uint64_t
QUICAckFrame::PacketNumberRange::size() const
{
  return this->_first - this->_last;
}

bool
QUICAckFrame::PacketNumberRange::contains(QUICPacketNumber x) const
{
  return static_cast<uint64_t>(this->_last) <= static_cast<uint64_t>(x) &&
         static_cast<uint64_t>(x) <= static_cast<uint64_t>(this->_first);
}

//
// QUICAckFrame::AckBlock
//
uint64_t
QUICAckFrame::AckBlock::gap() const
{
  return this->_gap;
}

uint64_t
QUICAckFrame::AckBlock::length() const
{
  return this->_length;
}

size_t
QUICAckFrame::AckBlock::size() const
{
  return QUICVariableInt::size(this->_gap) + QUICVariableInt::size(this->_length);
}

//
// QUICAckFrame::AckBlockSection
//
uint8_t
QUICAckFrame::AckBlockSection::count() const
{
  return this->_ack_blocks.size();
}

size_t
QUICAckFrame::AckBlockSection::size() const
{
  size_t n = 0;

  n += QUICVariableInt::size(this->_first_ack_block);

  for (auto &&block : *this) {
    n += block.size();
  }

  return n;
}

Ptr<IOBufferBlock>
QUICAckFrame::AckBlockSection::to_io_buffer_block(size_t limit) const
{
  Ptr<IOBufferBlock> block;
  size_t n = 0;

  if (limit < this->size()) {
    return block;
  }

  size_t written_len = 0;
  block              = make_ptr<IOBufferBlock>(new_IOBufferBlock());
  block->alloc(iobuffer_size_to_index(limit, BUFFER_SIZE_INDEX_32K));
  uint8_t *block_start = reinterpret_cast<uint8_t *>(block->start());

  QUICIntUtil::write_QUICVariableInt(this->_first_ack_block, block_start + n, &written_len);
  n += written_len;

  for (auto &&block : *this) {
    QUICIntUtil::write_QUICVariableInt(block.gap(), block_start + n, &written_len);
    n += written_len;
    QUICIntUtil::write_QUICVariableInt(block.length(), block_start + n, &written_len);
    n += written_len;
  }

  block->fill(n);
  return block;
}

uint64_t
QUICAckFrame::AckBlockSection::first_ack_block() const
{
  return this->_first_ack_block;
}

void
QUICAckFrame::AckBlockSection::add_ack_block(AckBlock block)
{
  this->_ack_blocks.push_back(block);
}

QUICAckFrame::AckBlockSection::const_iterator
QUICAckFrame::AckBlockSection::begin() const
{
  return const_iterator(0, &this->_ack_blocks);
}

QUICAckFrame::AckBlockSection::const_iterator
QUICAckFrame::AckBlockSection::end() const
{
  return const_iterator(this->_ack_blocks.size(), &this->_ack_blocks);
}

QUICAckFrame::AckBlockSection::const_iterator::const_iterator(uint8_t index, const std::vector<QUICAckFrame::AckBlock> *ack_blocks)
  : _index(index), _ack_blocks(ack_blocks)
{
  if (this->_ack_blocks->size()) {
    if (this->_ack_blocks->size() == this->_index) {
      this->_current_block = {UINT64_C(0), UINT64_C(0)};
    } else {
      this->_current_block = this->_ack_blocks->at(this->_index);
    }
  }
}

// FIXME: something wrong with clang-format?
const QUICAckFrame::AckBlock &
QUICAckFrame::AckBlockSection::const_iterator::operator++()
{
  ++(this->_index);

  if (this->_ack_blocks->size() == this->_index) {
    this->_current_block = {UINT64_C(0), UINT64_C(0)};
  } else {
    this->_current_block = this->_ack_blocks->at(this->_index);
  }

  return this->_current_block;
}

const bool
QUICAckFrame::AckBlockSection::const_iterator::operator!=(const const_iterator &ite) const
{
  return this->_index != ite._index;
}

const bool
QUICAckFrame::AckBlockSection::const_iterator::operator==(const const_iterator &ite) const
{
  return this->_index == ite._index;
}

QUICAckFrame::EcnSection::EcnSection(const uint8_t *buf, size_t len)
{
  uint8_t *pos = const_cast<uint8_t *>(buf);

  size_t field_len = 0;
  if (!read_varint(pos, LEFT_SPACE(pos), this->_ect0_count, field_len)) {
    return;
  }

  if (!read_varint(pos, LEFT_SPACE(pos), this->_ect1_count, field_len)) {
    return;
  }

  if (!read_varint(pos, LEFT_SPACE(pos), this->_ecn_ce_count, field_len)) {
    return;
  }

  this->_valid = true;
  this->_size  = FRAME_SIZE(pos);
}

bool
QUICAckFrame::EcnSection::valid() const
{
  return this->_valid;
}

size_t
QUICAckFrame::EcnSection::size() const
{
  return QUICVariableInt::size(this->_ect0_count) + QUICVariableInt::size(this->_ect1_count) +
         QUICVariableInt::size(this->_ecn_ce_count);
}

uint64_t
QUICAckFrame::EcnSection::ect0_count() const
{
  return this->_ect0_count;
}

uint64_t
QUICAckFrame::EcnSection::ect1_count() const
{
  return this->_ect1_count;
}

uint64_t
QUICAckFrame::EcnSection::ecn_ce_count() const
{
  return this->_ecn_ce_count;
}

//
// RESET_STREAM frame
//

QUICRstStreamFrame::QUICRstStreamFrame(QUICStreamId stream_id, QUICAppErrorCode error_code, QUICOffset final_offset, QUICFrameId id,
                                       QUICFrameGenerator *owner)
  : QUICFrame(id, owner), _stream_id(stream_id), _error_code(error_code), _final_offset(final_offset)
{
}

QUICRstStreamFrame::QUICRstStreamFrame(const uint8_t *buf, size_t len, const QUICPacketR *packet) : QUICFrame(0, nullptr, packet)
{
  this->parse(buf, len, packet);
}

void
QUICRstStreamFrame::parse(const uint8_t *buf, size_t len, const QUICPacketR *packet)
{
  ink_assert(len >= 1);
  this->_reset();
  this->_packet = packet;
  uint8_t *pos  = 1 + const_cast<uint8_t *>(buf);

  size_t field_len = 0;

  // Stream ID (i)
  if (!read_varint(pos, LEFT_SPACE(pos), this->_stream_id, field_len)) {
    return;
  }

  // Error Code (i)
  if (LEFT_SPACE(pos) < 1) {
    return;
  }
  if (!read_varint(pos, LEFT_SPACE(pos), this->_error_code, field_len)) {
    return;
  }

  // Final Offset (i)
  if (!read_varint(pos, LEFT_SPACE(pos), this->_final_offset, field_len)) {
    return;
  }

  this->_valid = true;
  this->_size  = FRAME_SIZE(pos);
}

void
QUICRstStreamFrame::_reset()
{
  this->_stream_id    = 0;
  this->_error_code   = 0;
  this->_final_offset = 0;

  this->_owner = nullptr;
  this->_id    = 0;
  this->_valid = false;
  this->_size  = 0;
}

QUICFrameType
QUICRstStreamFrame::type() const
{
  return QUICFrameType::RESET_STREAM;
}

size_t
QUICRstStreamFrame::size() const
{
  if (this->_size) {
    return this->_size;
  }

  return 1 + QUICVariableInt::size(this->_stream_id) + QUICVariableInt::size(this->_error_code) +
         QUICVariableInt::size(this->_final_offset);
}

Ptr<IOBufferBlock>
QUICRstStreamFrame::to_io_buffer_block(size_t limit) const
{
  Ptr<IOBufferBlock> block;
  size_t n = 0;

  if (limit < this->size()) {
    return block;
  }

  size_t written_len = 0;
  block              = make_ptr<IOBufferBlock>(new_IOBufferBlock());
  block->alloc(iobuffer_size_to_index(1 + 24, BUFFER_SIZE_INDEX_32K));
  uint8_t *block_start = reinterpret_cast<uint8_t *>(block->start());

  // Type
  block_start[0] = static_cast<uint8_t>(QUICFrameType::RESET_STREAM);
  n += 1;

  // Stream ID (i)
  QUICTypeUtil::write_QUICStreamId(this->_stream_id, block_start + n, &written_len);
  n += written_len;

  // Application Error Code (i)
  QUICTypeUtil::write_QUICAppErrorCode(this->_error_code, block_start + n, &written_len);
  n += written_len;

  // Final Size (i)
  QUICTypeUtil::write_QUICOffset(this->_final_offset, block_start + n, &written_len);
  n += written_len;

  block->fill(n);
  return block;
}

int
QUICRstStreamFrame::debug_msg(char *msg, size_t msg_len) const
{
  return snprintf(msg, msg_len, "RESET_STREAM size=%zu stream_id=%" PRIu64 " code=0x%" PRIx64, this->size(), this->stream_id(),
                  this->error_code());
}

QUICStreamId
QUICRstStreamFrame::stream_id() const
{
  return this->_stream_id;
}

QUICAppErrorCode
QUICRstStreamFrame::error_code() const
{
  return this->_error_code;
}

QUICOffset
QUICRstStreamFrame::final_offset() const
{
  return this->_final_offset;
}

//
// PING frame
//

QUICPingFrame::QUICPingFrame(const uint8_t *buf, size_t len, const QUICPacketR *packet) : QUICFrame(0, nullptr, packet)
{
  this->parse(buf, len, packet);
}

void
QUICPingFrame::parse(const uint8_t *buf, size_t len, const QUICPacketR *packet)
{
  this->_reset();
  this->_packet = packet;
  this->_valid  = true;
  this->_size   = 1;
}

QUICFrameType
QUICPingFrame::type() const
{
  return QUICFrameType::PING;
}

size_t
QUICPingFrame::size() const
{
  return 1;
}

Ptr<IOBufferBlock>
QUICPingFrame::to_io_buffer_block(size_t limit) const
{
  Ptr<IOBufferBlock> block;
  size_t n = 0;

  if (limit < this->size()) {
    return block;
  }

  block = make_ptr<IOBufferBlock>(new_IOBufferBlock());
  block->alloc(iobuffer_size_to_index(this->size(), BUFFER_SIZE_INDEX_32K));
  uint8_t *block_start = reinterpret_cast<uint8_t *>(block->start());

  // Type
  block_start[0] = static_cast<uint8_t>(QUICFrameType::PING);
  n += 1;

  block->fill(n);
  return block;
}

//
// PADDING frame
//
QUICPaddingFrame::QUICPaddingFrame(const uint8_t *buf, size_t len, const QUICPacketR *packet) : QUICFrame(0, nullptr, packet)
{
  this->parse(buf, len, packet);
}

void
QUICPaddingFrame::parse(const uint8_t *buf, size_t len, const QUICPacketR *packet)
{
  ink_assert(len >= 1);
  this->_reset();
  this->_packet = packet;
  this->_size   = 0;
  this->_valid  = true;
  // find out how many padding frames in this buf
  for (size_t i = 0; i < len; i++) {
    if (*(buf + i) == static_cast<uint8_t>(QUICFrameType::PADDING)) {
      ++this->_size;
    } else {
      break;
    }
  }
}

QUICFrameType
QUICPaddingFrame::type() const
{
  return QUICFrameType::PADDING;
}

size_t
QUICPaddingFrame::size() const
{
  return this->_size;
}

bool
QUICPaddingFrame::is_probing_frame() const
{
  return true;
}

Ptr<IOBufferBlock>
QUICPaddingFrame::to_io_buffer_block(size_t limit) const
{
  Ptr<IOBufferBlock> block;
  size_t n = 0;

  if (limit < this->size()) {
    return block;
  }

  block = make_ptr<IOBufferBlock>(new_IOBufferBlock());
  block->alloc(iobuffer_size_to_index(this->_size, BUFFER_SIZE_INDEX_32K));
  uint8_t *block_start = reinterpret_cast<uint8_t *>(block->start());

  memset(block_start, 0, this->_size);
  n = this->_size;

  block->fill(n);
  return block;
}

//
// CONNECTION_CLOSE frame
//
QUICConnectionCloseFrame::QUICConnectionCloseFrame(uint64_t error_code, QUICFrameType frame_type, uint64_t reason_phrase_length,
                                                   const char *reason_phrase, QUICFrameId id, QUICFrameGenerator *owner)
  : QUICFrame(id, owner),
    _type(0x1c),
    _error_code(error_code),
    _frame_type(frame_type),
    _reason_phrase_length(reason_phrase_length),
    _reason_phrase(reason_phrase)
{
}

QUICConnectionCloseFrame::QUICConnectionCloseFrame(uint64_t error_code, uint64_t reason_phrase_length, const char *reason_phrase,
                                                   QUICFrameId id, QUICFrameGenerator *owner)
  : QUICFrame(id, owner),
    _type(0x1d),
    _error_code(error_code),
    _reason_phrase_length(reason_phrase_length),
    _reason_phrase(reason_phrase)
{
}

QUICConnectionCloseFrame::QUICConnectionCloseFrame(const uint8_t *buf, size_t len, const QUICPacketR *packet)
  : QUICFrame(0, nullptr, packet)
{
  this->parse(buf, len, packet);
}

void
QUICConnectionCloseFrame::_reset()
{
  this->_error_code           = 0;
  this->_reason_phrase_length = 0;
  this->_reason_phrase        = nullptr;
  this->_frame_type           = QUICFrameType::UNKNOWN;

  this->_owner = nullptr;
  this->_id    = 0;
  this->_size  = 0;
  this->_valid = false;
}

void
QUICConnectionCloseFrame::parse(const uint8_t *buf, size_t len, const QUICPacketR *packet)
{
  ink_assert(len >= 1);
  this->_reset();
  this->_packet = packet;
  this->_type   = buf[0];
  uint8_t *pos  = const_cast<uint8_t *>(buf) + 1;

  size_t field_len = 0;
  uint64_t field   = 0;

  // Error Code (i)
  if (LEFT_SPACE(pos) < 1) {
    return;
  }
  read_varint(pos, LEFT_SPACE(pos), field, field_len);
  this->_error_code = field;

  if (this->_type == 0x1c) {
    // Frame Type (i)
    if (!read_varint(pos, LEFT_SPACE(pos), field, field_len)) {
      return;
    }
    this->_frame_type = static_cast<QUICFrameType>(field);

    /**
       Frame Type Field Accessor

       PADDING frame in Frame Type field means frame type that triggered the error is unknown.
       Return QUICFrameType::UNKNOWN when Frame Type field is PADDING (0x0).
     */
    if (this->_frame_type == QUICFrameType::PADDING) {
      this->_frame_type = QUICFrameType::UNKNOWN;
    }
  }

  // Reason Phrase Length (i)
  if (LEFT_SPACE(pos) < 1) {
    return;
  }
  if (!read_varint(pos, LEFT_SPACE(pos), this->_reason_phrase_length, field_len)) {
    return;
  }

  // Reason Phrase
  if (LEFT_SPACE(pos) < this->_reason_phrase_length) {
    return;
  }
  this->_reason_phrase = reinterpret_cast<const char *>(pos);

  this->_valid = true;
  pos += this->_reason_phrase_length;
  this->_size = FRAME_SIZE(pos);
}

QUICFrameType
QUICConnectionCloseFrame::type() const
{
  return QUICFrameType::CONNECTION_CLOSE;
}

size_t
QUICConnectionCloseFrame::size() const
{
  if (this->_size) {
    return this->_size;
  }

  return 1 + QUICVariableInt::size(sizeof(QUICTransErrorCode)) + QUICVariableInt::size(sizeof(QUICFrameType)) +
         QUICVariableInt::size(this->_reason_phrase_length) + this->_reason_phrase_length;
}

/**
   Store CONNECTION_CLOSE frame in buffer.

   PADDING frame in Frame Type field means frame type that triggered the error is unknown.
   When `_frame_type` is QUICFrameType::UNKNOWN, it's converted to QUICFrameType::PADDING (0x0).
 */
Ptr<IOBufferBlock>
QUICConnectionCloseFrame::to_io_buffer_block(size_t limit) const
{
  Ptr<IOBufferBlock> first_block;
  size_t n = 0;

  if (limit < this->size()) {
    return first_block;
  }

  // Create a block for Error Code(i) and Frame Type(i)
  size_t written_len = 0;
  first_block        = make_ptr<IOBufferBlock>(new_IOBufferBlock());
  first_block->alloc(iobuffer_size_to_index(1 + 24, BUFFER_SIZE_INDEX_32K));
  uint8_t *block_start = reinterpret_cast<uint8_t *>(first_block->start());

  // Type
  block_start[0] = this->_type;
  n += 1;

  // Error Code (i)
  QUICIntUtil::write_QUICVariableInt(this->_error_code, block_start + n, &written_len);
  n += written_len;

  // Frame Type (i)
  QUICFrameType frame_type = this->_frame_type;
  if (frame_type == QUICFrameType::UNKNOWN) {
    frame_type = QUICFrameType::PADDING;
  }
  QUICIntUtil::write_QUICVariableInt(static_cast<uint64_t>(frame_type), block_start + n, &written_len);
  n += written_len;

  // Reason Phrase Length (i)
  QUICIntUtil::write_QUICVariableInt(this->_reason_phrase_length, block_start + n, &written_len);
  n += written_len;

  first_block->fill(n);

  // Create a block for reason if necessary
  if (this->_reason_phrase_length != 0) {
    // Reason Phrase (*)
    Ptr<IOBufferBlock> reason_block = make_ptr<IOBufferBlock>(new_IOBufferBlock());
    reason_block->alloc(iobuffer_size_to_index(this->_reason_phrase_length, BUFFER_SIZE_INDEX_32K));
    memcpy(reinterpret_cast<uint8_t *>(reason_block->start()), this->_reason_phrase, this->_reason_phrase_length);
    reason_block->fill(this->_reason_phrase_length);

    // Append reason block to the first block
    first_block->next = reason_block;
  }

  // Return the chain
  return first_block;
}

int
QUICConnectionCloseFrame::debug_msg(char *msg, size_t msg_len) const
{
  int len;
  if (this->_type == 0x1c) {
    len =
      snprintf(msg, msg_len, "CONNECTION_CLOSE size=%zu code=%s (0x%" PRIx16 ") frame=%s", this->size(),
               QUICDebugNames::error_code(this->error_code()), this->error_code(), QUICDebugNames::frame_type(this->frame_type()));
  } else {
    // Application-specific error. It doesn't have a frame type and we don't know string representations of error codes.
    len = snprintf(msg, msg_len, "CONNECTION_CLOSE size=%zu code=0x%" PRIx16 " ", this->size(), this->error_code());
  }

  if (this->reason_phrase_length() != 0 && this->reason_phrase() != nullptr) {
    memcpy(msg + len, " reason=", 8);
    len += 8;

    int phrase_len = std::min(msg_len - len, static_cast<size_t>(this->reason_phrase_length()));
    memcpy(msg + len, this->reason_phrase(), phrase_len);
    len += phrase_len;
    msg[len] = '\0';
    ++len;
  }

  return len;
}

uint16_t
QUICConnectionCloseFrame::error_code() const
{
  return this->_error_code;
}

QUICFrameType
QUICConnectionCloseFrame::frame_type() const
{
  return this->_frame_type;
}

uint64_t
QUICConnectionCloseFrame::reason_phrase_length() const
{
  return this->_reason_phrase_length;
}

const char *
QUICConnectionCloseFrame::reason_phrase() const
{
  return this->_reason_phrase;
}

//
// MAX_DATA frame
//
QUICMaxDataFrame::QUICMaxDataFrame(uint64_t maximum_data, QUICFrameId id, QUICFrameGenerator *owner) : QUICFrame(id, owner)
{
  this->_maximum_data = maximum_data;
}

void
QUICMaxDataFrame::_reset()
{
  this->_maximum_data = 0;

  this->_owner = nullptr;
  this->_id    = 0;
  this->_valid = false;
  this->_size  = 0;
}

QUICMaxDataFrame::QUICMaxDataFrame(const uint8_t *buf, size_t len, const QUICPacketR *packet) : QUICFrame(0, nullptr, packet)
{
  this->parse(buf, len, packet);
}

void
QUICMaxDataFrame::parse(const uint8_t *buf, size_t len, const QUICPacketR *packet)
{
  ink_assert(len >= 1);
  this->_reset();
  this->_packet = packet;
  uint8_t *pos  = 1 + const_cast<uint8_t *>(buf);

  size_t field_len = 0;
  if (!read_varint(pos, LEFT_SPACE(pos), this->_maximum_data, field_len)) {
    return;
  }

  this->_valid = true;
  this->_size  = FRAME_SIZE(pos);
}

QUICFrameType
QUICMaxDataFrame::type() const
{
  return QUICFrameType::MAX_DATA;
}

size_t
QUICMaxDataFrame::size() const
{
  if (this->_size) {
    return this->_size;
  }

  return sizeof(QUICFrameType) + QUICVariableInt::size(this->_maximum_data);
}

Ptr<IOBufferBlock>
QUICMaxDataFrame::to_io_buffer_block(size_t limit) const
{
  Ptr<IOBufferBlock> block;
  size_t n = 0;

  if (limit < this->size()) {
    return block;
  }

  size_t written_len = 0;
  block              = make_ptr<IOBufferBlock>(new_IOBufferBlock());
  block->alloc(iobuffer_size_to_index(1 + sizeof(size_t), BUFFER_SIZE_INDEX_32K));
  uint8_t *block_start = reinterpret_cast<uint8_t *>(block->start());

  // Type
  block_start[0] = static_cast<uint8_t>(QUICFrameType::MAX_DATA);
  n += 1;

  // Maximum Data (i)
  QUICTypeUtil::write_QUICMaxData(this->_maximum_data, block_start + n, &written_len);
  n += written_len;

  block->fill(n);
  return block;
}

int
QUICMaxDataFrame::debug_msg(char *msg, size_t msg_len) const
{
  return snprintf(msg, msg_len, "MAX_DATA size=%zu maximum=%" PRIu64, this->size(), this->maximum_data());
}

uint64_t
QUICMaxDataFrame::maximum_data() const
{
  return this->_maximum_data;
}

//
// MAX_STREAM_DATA
//
QUICMaxStreamDataFrame::QUICMaxStreamDataFrame(QUICStreamId stream_id, uint64_t maximum_stream_data, QUICFrameId id,
                                               QUICFrameGenerator *owner)
  : QUICFrame(id, owner)
{
  this->_stream_id           = stream_id;
  this->_maximum_stream_data = maximum_stream_data;
}

void
QUICMaxStreamDataFrame::_reset()
{
  this->_stream_id           = 0;
  this->_maximum_stream_data = 0;

  this->_owner = nullptr;
  this->_id    = 0;
  this->_valid = false;
  this->_size  = 0;
}

QUICMaxStreamDataFrame::QUICMaxStreamDataFrame(const uint8_t *buf, size_t len, const QUICPacketR *packet)
  : QUICFrame(0, nullptr, packet)
{
  this->parse(buf, len, packet);
}

void
QUICMaxStreamDataFrame::parse(const uint8_t *buf, size_t len, const QUICPacketR *packet)
{
  ink_assert(len >= 1);
  this->_reset();
  this->_packet = packet;
  uint8_t *pos  = const_cast<uint8_t *>(buf) + 1;

  size_t field_len = 0;
  if (!read_varint(pos, LEFT_SPACE(pos), this->_stream_id, field_len)) {
    return;
  }

  if (!read_varint(pos, LEFT_SPACE(pos), this->_maximum_stream_data, field_len)) {
    return;
  }

  this->_valid = true;
  this->_size  = FRAME_SIZE(pos);
}

QUICFrameType
QUICMaxStreamDataFrame::type() const
{
  return QUICFrameType::MAX_STREAM_DATA;
}

size_t
QUICMaxStreamDataFrame::size() const
{
  if (this->_size) {
    return this->_size;
  }

  return sizeof(QUICFrameType) + QUICVariableInt::size(this->_maximum_stream_data) + QUICVariableInt::size(this->_stream_id);
}

Ptr<IOBufferBlock>
QUICMaxStreamDataFrame::to_io_buffer_block(size_t limit) const
{
  Ptr<IOBufferBlock> block;
  size_t n = 0;

  if (limit < this->size()) {
    return block;
  }

  size_t written_len = 0;
  block              = make_ptr<IOBufferBlock>(new_IOBufferBlock());
  block->alloc(iobuffer_size_to_index(1 + sizeof(uint64_t) + sizeof(size_t), BUFFER_SIZE_INDEX_32K));
  uint8_t *block_start = reinterpret_cast<uint8_t *>(block->start());

  // Type
  block_start[0] = static_cast<uint8_t>(QUICFrameType::MAX_STREAM_DATA);
  n += 1;

  // Stream ID (i)
  QUICTypeUtil::write_QUICStreamId(this->_stream_id, block_start + n, &written_len);
  n += written_len;

  // Maximum Stream Data (i)
  QUICTypeUtil::write_QUICMaxData(this->_maximum_stream_data, block_start + n, &written_len);
  n += written_len;

  block->fill(n);
  return block;
}

int
QUICMaxStreamDataFrame::debug_msg(char *msg, size_t msg_len) const
{
  return snprintf(msg, msg_len, "MAX_STREAM_DATA size=%zu id=%" PRIu64 " maximum=%" PRIu64, this->size(), this->stream_id(),
                  this->maximum_stream_data());
}

QUICStreamId
QUICMaxStreamDataFrame::stream_id() const
{
  return this->_stream_id;
}

uint64_t
QUICMaxStreamDataFrame::maximum_stream_data() const
{
  return this->_maximum_stream_data;
}

//
// MAX_STREAMS
//
QUICMaxStreamsFrame::QUICMaxStreamsFrame(QUICStreamId maximum_streams, QUICFrameId id, QUICFrameGenerator *owner)
  : QUICFrame(id, owner)
{
  this->_maximum_streams = maximum_streams;
}

void
QUICMaxStreamsFrame::_reset()
{
  this->_maximum_streams = 0;

  this->_owner = nullptr;
  this->_id    = 0;
  this->_valid = false;
  this->_size  = 0;
}

QUICMaxStreamsFrame::QUICMaxStreamsFrame(const uint8_t *buf, size_t len, const QUICPacketR *packet) : QUICFrame(0, nullptr, packet)
{
  this->parse(buf, len, packet);
}

void
QUICMaxStreamsFrame::parse(const uint8_t *buf, size_t len, const QUICPacketR *packet)
{
  ink_assert(len >= 1);
  this->_reset();
  this->_packet = packet;
  uint8_t *pos  = const_cast<uint8_t *>(buf) + 1;

  size_t field_len = 0;
  if (!read_varint(pos, LEFT_SPACE(pos), this->_maximum_streams, field_len)) {
    return;
  }

  this->_valid = true;
  this->_size  = FRAME_SIZE(pos);
}

QUICFrameType
QUICMaxStreamsFrame::type() const
{
  return QUICFrameType::MAX_STREAMS;
}

size_t
QUICMaxStreamsFrame::size() const
{
  if (this->_size) {
    return this->_size;
  }

  return sizeof(QUICFrameType) + QUICVariableInt::size(this->_maximum_streams);
}

Ptr<IOBufferBlock>
QUICMaxStreamsFrame::to_io_buffer_block(size_t limit) const
{
  Ptr<IOBufferBlock> block;
  size_t n = 0;

  if (limit < this->size()) {
    return block;
  }

  size_t written_len = 0;
  block              = make_ptr<IOBufferBlock>(new_IOBufferBlock());
  block->alloc(iobuffer_size_to_index(1 + sizeof(size_t), BUFFER_SIZE_INDEX_32K));
  uint8_t *block_start = reinterpret_cast<uint8_t *>(block->start());

  // Type
  block_start[0] = static_cast<uint8_t>(QUICFrameType::MAX_STREAMS);
  n += 1;

  // Maximum Streams (i)
  QUICTypeUtil::write_QUICStreamId(this->_maximum_streams, block_start + n, &written_len);
  n += written_len;

  block->fill(n);
  return block;
}

uint64_t
QUICMaxStreamsFrame::maximum_streams() const
{
  return this->_maximum_streams;
}

//
// DATA_BLOCKED frame
//
QUICDataBlockedFrame::QUICDataBlockedFrame(const uint8_t *buf, size_t len, const QUICPacketR *packet)
  : QUICFrame(0, nullptr, packet)
{
  this->parse(buf, len, packet);
}

void
QUICDataBlockedFrame::_reset()
{
  this->_offset = 0;

  this->_owner = nullptr;
  this->_id    = 0;
  this->_valid = false;
  this->_size  = 0;
}

void
QUICDataBlockedFrame::parse(const uint8_t *buf, size_t len, const QUICPacketR *packet)
{
  ink_assert(len >= 1);
  this->_reset();
  this->_packet = packet;
  uint8_t *pos  = const_cast<uint8_t *>(buf) + 1;

  size_t field_len = 0;
  if (!read_varint(pos, LEFT_SPACE(pos), this->_offset, field_len)) {
    return;
  }

  this->_valid = true;
  this->_size  = FRAME_SIZE(pos);
}

int
QUICDataBlockedFrame::debug_msg(char *msg, size_t msg_len) const
{
  return snprintf(msg, msg_len, "DATA_BLOCKED size=%zu offset=%" PRIu64, this->size(), this->offset());
}

QUICFrameType
QUICDataBlockedFrame::type() const
{
  return QUICFrameType::DATA_BLOCKED;
}

size_t
QUICDataBlockedFrame::size() const
{
  if (this->_size) {
    return this->_size;
  }

  return sizeof(QUICFrameType) + QUICVariableInt::size(this->offset());
}

Ptr<IOBufferBlock>
QUICDataBlockedFrame::to_io_buffer_block(size_t limit) const
{
  Ptr<IOBufferBlock> block;
  size_t n = 0;

  if (limit < this->size()) {
    return block;
  }

  size_t written_len = 0;
  block              = make_ptr<IOBufferBlock>(new_IOBufferBlock());
  block->alloc(iobuffer_size_to_index(1 + sizeof(size_t), BUFFER_SIZE_INDEX_32K));
  uint8_t *block_start = reinterpret_cast<uint8_t *>(block->start());

  // Type
  block_start[0] = static_cast<uint8_t>(QUICFrameType::DATA_BLOCKED);
  n += 1;

  // Data Limit (i)
  QUICTypeUtil::write_QUICOffset(this->_offset, block_start + n, &written_len);
  n += written_len;

  block->fill(n);
  return block;
}

QUICOffset
QUICDataBlockedFrame::offset() const
{
  return this->_offset;
}

//
// STREAM_DATA_BLOCKED frame
//
QUICStreamDataBlockedFrame::QUICStreamDataBlockedFrame(const uint8_t *buf, size_t len, const QUICPacketR *packet)
  : QUICFrame(0, nullptr, packet)
{
  this->parse(buf, len, packet);
}

void
QUICStreamDataBlockedFrame::_reset()
{
  this->_stream_id = 0;
  this->_offset    = 0;

  this->_owner = nullptr;
  this->_id    = 0;
  this->_valid = false;
  this->_size  = 0;
}

void
QUICStreamDataBlockedFrame::parse(const uint8_t *buf, size_t len, const QUICPacketR *packet)
{
  ink_assert(len >= 1);
  this->_reset();
  this->_packet = packet;
  uint8_t *pos  = const_cast<uint8_t *>(buf) + 1;

  size_t field_len = 0;
  if (!read_varint(pos, LEFT_SPACE(pos), this->_stream_id, field_len)) {
    return;
  }

  if (!read_varint(pos, LEFT_SPACE(pos), this->_offset, field_len)) {
    return;
  }

  this->_valid = true;
  this->_size  = FRAME_SIZE(pos);
}

int
QUICStreamDataBlockedFrame::debug_msg(char *msg, size_t msg_len) const
{
  return snprintf(msg, msg_len, "STREAM_DATA_BLOCKED size=%zu id=%" PRIu64 " offset=%" PRIu64, this->size(), this->stream_id(),
                  this->offset());
}

QUICFrameType
QUICStreamDataBlockedFrame::type() const
{
  return QUICFrameType::STREAM_DATA_BLOCKED;
}

size_t
QUICStreamDataBlockedFrame::size() const
{
  if (this->_size) {
    return this->_size;
  }

  return sizeof(QUICFrameType) + QUICVariableInt::size(this->_offset) + QUICVariableInt::size(this->_stream_id);
}

Ptr<IOBufferBlock>
QUICStreamDataBlockedFrame::to_io_buffer_block(size_t limit) const
{
  Ptr<IOBufferBlock> block;
  size_t n = 0;

  if (limit < this->size()) {
    return block;
  }

  size_t written_len = 0;
  block              = make_ptr<IOBufferBlock>(new_IOBufferBlock());
  block->alloc(iobuffer_size_to_index(1 + sizeof(size_t), BUFFER_SIZE_INDEX_32K));
  uint8_t *block_start = reinterpret_cast<uint8_t *>(block->start());

  // Type
  block_start[0] = static_cast<uint8_t>(QUICFrameType::STREAM_DATA_BLOCKED);
  n += 1;

  // Stream ID (i)
  QUICTypeUtil::write_QUICStreamId(this->_stream_id, block_start + n, &written_len);
  n += written_len;

  // Data Limit (i)
  QUICTypeUtil::write_QUICOffset(this->_offset, block_start + n, &written_len);
  n += written_len;

  block->fill(n);
  return block;
}

QUICStreamId
QUICStreamDataBlockedFrame::stream_id() const
{
  return this->_stream_id;
}

QUICOffset
QUICStreamDataBlockedFrame::offset() const
{
  return this->_offset;
}

//
// STREAMS_BLOCKED frame
//
QUICStreamIdBlockedFrame::QUICStreamIdBlockedFrame(const uint8_t *buf, size_t len, const QUICPacketR *packet)
  : QUICFrame(0, nullptr, packet)
{
  this->parse(buf, len, packet);
}

void
QUICStreamIdBlockedFrame::_reset()
{
  this->_stream_id = 0;

  this->_owner = nullptr;
  this->_id    = 0;
  this->_size  = 0;
  this->_valid = false;
}

void
QUICStreamIdBlockedFrame::parse(const uint8_t *buf, size_t len, const QUICPacketR *packet)
{
  ink_assert(len >= 1);
  this->_reset();
  this->_packet = packet;
  uint8_t *pos  = const_cast<uint8_t *>(buf) + 1;

  size_t field_len = 0;
  if (!read_varint(pos, LEFT_SPACE(pos), this->_stream_id, field_len)) {
    return;
  }

  this->_valid = true;
  this->_size  = FRAME_SIZE(pos);
}

QUICFrameType
QUICStreamIdBlockedFrame::type() const
{
  return QUICFrameType::STREAMS_BLOCKED;
}

size_t
QUICStreamIdBlockedFrame::size() const
{
  if (this->_size) {
    return this->_size;
  }

  return sizeof(QUICFrameType) + QUICVariableInt::size(this->_stream_id);
}

Ptr<IOBufferBlock>
QUICStreamIdBlockedFrame::to_io_buffer_block(size_t limit) const
{
  Ptr<IOBufferBlock> block;
  size_t n = 0;

  if (limit < this->size()) {
    return block;
  }

  size_t written_len = 0;
  block              = make_ptr<IOBufferBlock>(new_IOBufferBlock());
  block->alloc(iobuffer_size_to_index(1 + sizeof(size_t), BUFFER_SIZE_INDEX_32K));
  uint8_t *block_start = reinterpret_cast<uint8_t *>(block->start());

  // Type
  block_start[0] = static_cast<uint8_t>(QUICFrameType::STREAMS_BLOCKED);
  n += 1;

  // Stream Limit (i)
  QUICTypeUtil::write_QUICStreamId(this->_stream_id, block_start + n, &written_len);
  n += written_len;

  block->fill(n);
  return block;
}

QUICStreamId
QUICStreamIdBlockedFrame::stream_id() const
{
  return this->_stream_id;
}

//
// NEW_CONNECTION_ID frame
//
QUICNewConnectionIdFrame::QUICNewConnectionIdFrame(const uint8_t *buf, size_t len, const QUICPacketR *packet)
  : QUICFrame(0, nullptr, packet)
{
  this->parse(buf, len, packet);
}

void
QUICNewConnectionIdFrame::_reset()
{
  this->_sequence        = 0;
  this->_retire_prior_to = 0;
  this->_connection_id   = QUICConnectionId::ZERO();

  this->_owner = nullptr;
  this->_id    = 0;
  this->_valid = false;
  this->_size  = 0;
}

void
QUICNewConnectionIdFrame::parse(const uint8_t *buf, size_t len, const QUICPacketR *packet)
{
  ink_assert(len >= 1);
  this->_reset();
  this->_packet = packet;
  uint8_t *pos  = const_cast<uint8_t *>(buf) + 1;

  // Sequence Number (i)
  size_t field_len = 0;
  if (!read_varint(pos, LEFT_SPACE(pos), this->_sequence, field_len)) {
    return;
  }

  // Retire Prior To (i)
  if (LEFT_SPACE(pos) < 1) {
    return;
  }
  if (!read_varint(pos, LEFT_SPACE(pos), this->_retire_prior_to, field_len)) {
    return;
  }

  // Length (8)
  if (LEFT_SPACE(pos) < 1) {
    return;
  }
  size_t cid_len = *pos;
  pos += 1;

  // Connection ID (8..160)
  if (LEFT_SPACE(pos) < cid_len) {
    return;
  }
  this->_connection_id = QUICTypeUtil::read_QUICConnectionId(pos, cid_len);
  pos += cid_len;

  // Stateless Reset Token (128)
  if (LEFT_SPACE(pos) < QUICStatelessResetToken::LEN) {
    return;
  }

  this->_stateless_reset_token = QUICStatelessResetToken(pos);
  this->_valid                 = true;
  this->_size                  = FRAME_SIZE(pos) + QUICStatelessResetToken::LEN;
}

QUICFrameType
QUICNewConnectionIdFrame::type() const
{
  return QUICFrameType::NEW_CONNECTION_ID;
}

size_t
QUICNewConnectionIdFrame::size() const
{
  if (this->_size) {
    return this->_size;
  }

  return sizeof(QUICFrameType) + QUICVariableInt::size(this->_sequence) + QUICVariableInt::size(this->_retire_prior_to) + 1 +
         this->_connection_id.length() + QUICStatelessResetToken::LEN;
}

Ptr<IOBufferBlock>
QUICNewConnectionIdFrame::to_io_buffer_block(size_t limit) const
{
  Ptr<IOBufferBlock> block;
  size_t n = 0;

  if (limit < this->size()) {
    return block;
  }

  size_t written_len = 0;
  block              = make_ptr<IOBufferBlock>(new_IOBufferBlock());
  block->alloc(iobuffer_size_to_index(1 + sizeof(uint64_t) + sizeof(uint64_t) + 1 + QUICConnectionId::MAX_LENGTH +
                                        QUICStatelessResetToken::LEN,
                                      BUFFER_SIZE_INDEX_32K));
  uint8_t *block_start = reinterpret_cast<uint8_t *>(block->start());

  // Type
  block_start[0] = static_cast<uint8_t>(QUICFrameType::NEW_CONNECTION_ID);
  n += 1;

  // Sequence Number (i)
  QUICIntUtil::write_QUICVariableInt(this->_sequence, block_start + n, &written_len);
  n += written_len;

  // Retire Prior To (i)
  QUICIntUtil::write_QUICVariableInt(this->_retire_prior_to, block_start + n, &written_len);
  n += written_len;

  // Length (8)
  *(block_start + n) = this->_connection_id.length();
  n += 1;

  // Connection ID (8..160)
  QUICTypeUtil::write_QUICConnectionId(this->_connection_id, block_start + n, &written_len);
  n += written_len;

  // Stateless Reset Token (128)
  memcpy(block_start + n, this->_stateless_reset_token.buf(), QUICStatelessResetToken::LEN);
  n += QUICStatelessResetToken::LEN;

  block->fill(n);
  return block;
}

int
QUICNewConnectionIdFrame::debug_msg(char *msg, size_t msg_len) const
{
  return snprintf(msg, msg_len, "NEW_CONNECTION_ID size=%zu seq=%" PRIu64 " rpt=%" PRIu64 " cid=0x%s srt=%02x%02x%02x%02x",
                  this->size(), this->sequence(), this->retire_prior_to(), this->connection_id().hex().c_str(),
                  this->stateless_reset_token().buf()[0], this->stateless_reset_token().buf()[1],
                  this->stateless_reset_token().buf()[2], this->stateless_reset_token().buf()[3]);
}

uint64_t
QUICNewConnectionIdFrame::sequence() const
{
  return this->_sequence;
}

uint64_t
QUICNewConnectionIdFrame::retire_prior_to() const
{
  return this->_retire_prior_to;
}

QUICConnectionId
QUICNewConnectionIdFrame::connection_id() const
{
  return this->_connection_id;
}

QUICStatelessResetToken
QUICNewConnectionIdFrame::stateless_reset_token() const
{
  return this->_stateless_reset_token;
}

//
// STOP_SENDING frame
//

QUICStopSendingFrame::QUICStopSendingFrame(QUICStreamId stream_id, QUICAppErrorCode error_code, QUICFrameId id,
                                           QUICFrameGenerator *owner)
  : QUICFrame(id, owner), _stream_id(stream_id), _error_code(error_code)
{
}

void
QUICStopSendingFrame::_reset()
{
  this->_stream_id  = 0;
  this->_error_code = 0;

  this->_owner = nullptr;
  this->_id    = 0;
  this->_valid = false;
  this->_size  = 0;
}

QUICStopSendingFrame::QUICStopSendingFrame(const uint8_t *buf, size_t len, const QUICPacketR *packet)
  : QUICFrame(0, nullptr, packet)
{
  this->parse(buf, len, packet);
}

void
QUICStopSendingFrame::parse(const uint8_t *buf, size_t len, const QUICPacketR *packet)
{
  ink_assert(len >= 1);
  this->_reset();
  this->_packet = packet;
  uint8_t *pos  = const_cast<uint8_t *>(buf) + 1;

  // Stream ID (i)
  size_t field_len = 0;
  if (!read_varint(pos, LEFT_SPACE(pos), this->_stream_id, field_len)) {
    return;
  }

  // Error Code (i)
  if (LEFT_SPACE(pos) < 1) {
    return;
  }
  if (!read_varint(pos, LEFT_SPACE(pos), this->_error_code, field_len)) {
    return;
  }

  this->_valid = true;
  this->_size  = FRAME_SIZE(pos);
}

QUICFrameType
QUICStopSendingFrame::type() const
{
  return QUICFrameType::STOP_SENDING;
}

size_t
QUICStopSendingFrame::size() const
{
  if (this->_size) {
    return this->_size;
  }

  return sizeof(QUICFrameType) + QUICVariableInt::size(this->_stream_id) + QUICVariableInt::size(sizeof(QUICAppErrorCode));
}

Ptr<IOBufferBlock>
QUICStopSendingFrame::to_io_buffer_block(size_t limit) const
{
  Ptr<IOBufferBlock> block;
  size_t n = 0;

  if (limit < this->size()) {
    return block;
  }

  size_t written_len = 0;
  block              = make_ptr<IOBufferBlock>(new_IOBufferBlock());
  block->alloc(iobuffer_size_to_index(1 + 24, BUFFER_SIZE_INDEX_32K));
  uint8_t *block_start = reinterpret_cast<uint8_t *>(block->start());

  // Type
  block_start[0] = static_cast<uint8_t>(QUICFrameType::STOP_SENDING);
  n += 1;

  // Stream ID (i)
  QUICTypeUtil::write_QUICStreamId(this->_stream_id, block_start + n, &written_len);
  n += written_len;

  // Application Error Code (i)
  QUICTypeUtil::write_QUICAppErrorCode(this->_error_code, block_start + n, &written_len);
  n += written_len;

  block->fill(n);
  return block;
}

QUICAppErrorCode
QUICStopSendingFrame::error_code() const
{
  return this->_error_code;
}

QUICStreamId
QUICStopSendingFrame::stream_id() const
{
  return this->_stream_id;
}

//
// PATH_CHALLENGE frame
//
QUICPathChallengeFrame::QUICPathChallengeFrame(const uint8_t *buf, size_t len, const QUICPacketR *packet)
  : QUICFrame(0, nullptr, packet)
{
  this->parse(buf, len, packet);
}

void
QUICPathChallengeFrame::_reset()
{
  this->_data  = nullptr;
  this->_owner = nullptr;
  this->_id    = 0;
  this->_valid = false;
  this->_size  = 0;
}

void
QUICPathChallengeFrame::parse(const uint8_t *buf, size_t len, const QUICPacketR *packet)
{
  ink_assert(len >= 1);
  this->_reset();
  this->_packet = packet;
  uint8_t *pos  = const_cast<uint8_t *>(buf) + 1;

  if (LEFT_SPACE(pos) < QUICPathChallengeFrame::DATA_LEN) {
    return;
  }

  this->_data = ats_unique_malloc(QUICPathChallengeFrame::DATA_LEN);
  memcpy(this->_data.get(), pos, QUICPathChallengeFrame::DATA_LEN);
  this->_valid = true;
  this->_size  = FRAME_SIZE(pos) + QUICPathChallengeFrame::DATA_LEN;
}

QUICFrameType
QUICPathChallengeFrame::type() const
{
  return QUICFrameType::PATH_CHALLENGE;
}

size_t
QUICPathChallengeFrame::size() const
{
  if (this->_size) {
    return this->_size;
  }

  return 1 + QUICPathChallengeFrame::DATA_LEN;
}

bool
QUICPathChallengeFrame::is_probing_frame() const
{
  return true;
}

Ptr<IOBufferBlock>
QUICPathChallengeFrame::to_io_buffer_block(size_t limit) const
{
  Ptr<IOBufferBlock> block;
  size_t n = 0;

  if (limit < this->size()) {
    return block;
  }

  block = make_ptr<IOBufferBlock>(new_IOBufferBlock());
  block->alloc(iobuffer_size_to_index(1 + QUICPathChallengeFrame::DATA_LEN, BUFFER_SIZE_INDEX_32K));
  uint8_t *block_start = reinterpret_cast<uint8_t *>(block->start());

  // Type
  block_start[0] = static_cast<uint8_t>(QUICFrameType::PATH_CHALLENGE);
  n += 1;

  // Data (64)
  memcpy(block_start + n, this->data(), QUICPathChallengeFrame::DATA_LEN);
  n += QUICPathChallengeFrame::DATA_LEN;

  block->fill(n);
  return block;
}

int
QUICPathChallengeFrame::debug_msg(char *msg, size_t msg_len) const
{
  auto data = this->data();
  return snprintf(msg, msg_len, "PATH_CHALLENGE size=%zu data=0x%02x%02x%02x%02x%02x%02x%02x%02x", this->size(), data[0], data[1],
                  data[2], data[3], data[4], data[5], data[6], data[7]);
}

const uint8_t *
QUICPathChallengeFrame::data() const
{
  return this->_data.get();
}

//
// PATH_RESPONSE frame
//
QUICPathResponseFrame::QUICPathResponseFrame(const uint8_t *buf, size_t len, const QUICPacketR *packet)
  : QUICFrame(0, nullptr, packet)
{
  this->parse(buf, len, packet);
}

void
QUICPathResponseFrame::_reset()
{
  this->_data  = nullptr;
  this->_owner = nullptr;
  this->_id    = 0;
  this->_valid = false;
  this->_size  = 0;
}

Ptr<IOBufferBlock>
QUICPathResponseFrame::to_io_buffer_block(size_t limit) const
{
  Ptr<IOBufferBlock> block;
  size_t n = 0;

  if (limit < this->size()) {
    return block;
  }

  block = make_ptr<IOBufferBlock>(new_IOBufferBlock());
  block->alloc(iobuffer_size_to_index(1 + QUICPathResponseFrame::DATA_LEN, BUFFER_SIZE_INDEX_32K));
  uint8_t *block_start = reinterpret_cast<uint8_t *>(block->start());

  // Type
  block_start[0] = static_cast<uint8_t>(QUICFrameType::PATH_RESPONSE);
  n += 1;

  // Data (64)
  memcpy(block_start + n, this->data(), QUICPathChallengeFrame::DATA_LEN);
  n += QUICPathChallengeFrame::DATA_LEN;

  block->fill(n);
  return block;
}

void
QUICPathResponseFrame::parse(const uint8_t *buf, size_t len, const QUICPacketR *packet)
{
  ink_assert(len >= 1);
  this->_reset();
  this->_packet = packet;
  uint8_t *pos  = const_cast<uint8_t *>(buf) + 1;

  if (LEFT_SPACE(pos) < QUICPathChallengeFrame::DATA_LEN) {
    return;
  }

  this->_data = ats_unique_malloc(QUICPathChallengeFrame::DATA_LEN);
  memcpy(this->_data.get(), pos, QUICPathChallengeFrame::DATA_LEN);
  this->_valid = true;
  this->_size  = FRAME_SIZE(pos) + QUICPathChallengeFrame::DATA_LEN;
}

QUICFrameType
QUICPathResponseFrame::type() const
{
  return QUICFrameType::PATH_RESPONSE;
}

size_t
QUICPathResponseFrame::size() const
{
  return 1 + 8;
}

bool
QUICPathResponseFrame::is_probing_frame() const
{
  return true;
}

int
QUICPathResponseFrame::debug_msg(char *msg, size_t msg_len) const
{
  auto data = this->data();
  return snprintf(msg, msg_len, "PATH_RESPONSE size=%zu data=0x%02x%02x%02x%02x%02x%02x%02x%02x", this->size(), data[0], data[1],
                  data[2], data[3], data[4], data[5], data[6], data[7]);
}

const uint8_t *
QUICPathResponseFrame::data() const
{
  return this->_data.get();
}

//
// QUICNewTokenFrame
//
QUICNewTokenFrame::QUICNewTokenFrame(const uint8_t *buf, size_t len, const QUICPacketR *packet) : QUICFrame(0, nullptr, packet)
{
  this->parse(buf, len, packet);
}

void
QUICNewTokenFrame::_reset()
{
  this->_token        = nullptr;
  this->_token_length = 0;

  this->_owner = nullptr;
  this->_id    = 0;
  this->_valid = false;
  this->_size  = 0;
}

void
QUICNewTokenFrame::parse(const uint8_t *buf, size_t len, const QUICPacketR *packet)
{
  ink_assert(len >= 1);
  this->_reset();
  this->_packet = packet;
  uint8_t *pos  = const_cast<uint8_t *>(buf) + 1;

  size_t field_len = 0;
  if (!read_varint(pos, LEFT_SPACE(pos), this->_token_length, field_len)) {
    return;
  }

  if (LEFT_SPACE(pos) < this->_token_length) {
    return;
  }

  this->_token = ats_unique_malloc(this->_token_length);
  memcpy(this->_token.get(), pos, this->_token_length);
  this->_valid = true;
  this->_size  = FRAME_SIZE(pos) + this->_token_length;
}

QUICFrameType
QUICNewTokenFrame::type() const
{
  return QUICFrameType::NEW_TOKEN;
}

size_t
QUICNewTokenFrame::size() const
{
  if (this->_size) {
    return this->_size;
  }

  return 1 + QUICVariableInt::size(this->_token_length) + this->token_length();
}

Ptr<IOBufferBlock>
QUICNewTokenFrame::to_io_buffer_block(size_t limit) const
{
  Ptr<IOBufferBlock> block;
  size_t n = 0;

  if (limit < this->size()) {
    return block;
  }

  size_t written_len = 0;
  block              = make_ptr<IOBufferBlock>(new_IOBufferBlock());
  block->alloc(iobuffer_size_to_index(1 + 24, BUFFER_SIZE_INDEX_32K));
  uint8_t *block_start = reinterpret_cast<uint8_t *>(block->start());

  // Type
  block_start[0] = static_cast<uint8_t>(QUICFrameType::NEW_TOKEN);
  n += 1;

  // Token Length (i)
  QUICIntUtil::write_QUICVariableInt(this->_token_length, block_start + n, &written_len);
  n += written_len;

  // Token (*)
  memcpy(block_start + n, this->token(), this->token_length());
  n += this->token_length();

  block->fill(n);
  return block;
}

uint64_t
QUICNewTokenFrame::token_length() const
{
  return this->_token_length;
}

const uint8_t *
QUICNewTokenFrame::token() const
{
  return this->_token.get();
}

//
// RETIRE_CONNECTION_ID frame
//
QUICRetireConnectionIdFrame::QUICRetireConnectionIdFrame(const uint8_t *buf, size_t len, const QUICPacketR *packet)
  : QUICFrame(0, nullptr, packet)
{
  this->parse(buf, len, packet);
}

void
QUICRetireConnectionIdFrame::_reset()
{
  this->_seq_num = 0;

  this->_owner = nullptr;
  this->_id    = 0;
  this->_valid = false;
  this->_size  = 0;
  this->_size  = 0;
}

void
QUICRetireConnectionIdFrame::parse(const uint8_t *buf, size_t len, const QUICPacketR *packet)
{
  ink_assert(len >= 1);
  this->_reset();
  this->_packet = packet;
  uint8_t *pos  = const_cast<uint8_t *>(buf) + 1;

  size_t field_len = 0;
  if (!read_varint(pos, LEFT_SPACE(pos), this->_seq_num, field_len)) {
    return;
  }

  this->_valid = true;
  this->_size  = FRAME_SIZE(pos);
}

QUICFrameType
QUICRetireConnectionIdFrame::type() const
{
  return QUICFrameType::RETIRE_CONNECTION_ID;
}

size_t
QUICRetireConnectionIdFrame::size() const
{
  if (this->_size) {
    return this->_size;
  }

  return sizeof(QUICFrameType) + QUICVariableInt::size(this->_seq_num);
}

Ptr<IOBufferBlock>
QUICRetireConnectionIdFrame::to_io_buffer_block(size_t limit) const
{
  Ptr<IOBufferBlock> block;
  size_t n = 0;

  if (limit < this->size()) {
    return block;
  }

  size_t written_len = 0;
  block              = make_ptr<IOBufferBlock>(new_IOBufferBlock());
  block->alloc(iobuffer_size_to_index(1 + sizeof(uint64_t), BUFFER_SIZE_INDEX_32K));
  uint8_t *block_start = reinterpret_cast<uint8_t *>(block->start());

  // Type
  block_start[0] = static_cast<uint8_t>(QUICFrameType::RETIRE_CONNECTION_ID);
  n += 1;

  // Sequence Number (i)
  QUICIntUtil::write_QUICVariableInt(this->_seq_num, block_start + n, &written_len);
  n += written_len;

  block->fill(n);
  return block;
}

int
QUICRetireConnectionIdFrame::debug_msg(char *msg, size_t msg_len) const
{
  return snprintf(msg, msg_len, "RETIRE_CONNECTION_ID size=%zu seq_num=%" PRIu64, this->size(), this->seq_num());
}

uint64_t
QUICRetireConnectionIdFrame::seq_num() const
{
  return this->_seq_num;
}

//
// HANDSHAKE_DONE frame
//

QUICHandshakeDoneFrame::QUICHandshakeDoneFrame(const uint8_t *buf, size_t len, const QUICPacketR *packet)
  : QUICFrame(0, nullptr, packet)
{
  this->parse(buf, len, packet);
}

void
QUICHandshakeDoneFrame::parse(const uint8_t *buf, size_t len, const QUICPacketR *packet)
{
  this->_reset();
  this->_packet = packet;
  this->_valid  = true;
  this->_size   = 1;
}

QUICFrameType
QUICHandshakeDoneFrame::type() const
{
  return QUICFrameType::HANDSHAKE_DONE;
}

size_t
QUICHandshakeDoneFrame::size() const
{
  return 1;
}

Ptr<IOBufferBlock>
QUICHandshakeDoneFrame::to_io_buffer_block(size_t limit) const
{
  Ptr<IOBufferBlock> block;
  size_t n = 0;

  if (limit < this->size()) {
    return block;
  }

  block = make_ptr<IOBufferBlock>(new_IOBufferBlock());
  block->alloc(iobuffer_size_to_index(this->size(), BUFFER_SIZE_INDEX_32K));
  uint8_t *block_start = reinterpret_cast<uint8_t *>(block->start());

  // Type
  block_start[0] = static_cast<uint8_t>(QUICFrameType::HANDSHAKE_DONE);
  n += 1;

  block->fill(n);
  return block;
}

//
// UNKNOWN
//
QUICFrameType
QUICUnknownFrame::type() const
{
  return QUICFrameType::UNKNOWN;
}

size_t
QUICUnknownFrame::size() const
{
  // FIXME size should be readable
  return 0;
}

Ptr<IOBufferBlock>
QUICUnknownFrame::to_io_buffer_block(size_t limit) const
{
  Ptr<IOBufferBlock> block;
  return block;
}

void
QUICUnknownFrame::parse(const uint8_t *buf, size_t len, const QUICPacketR *packet)
{
  this->_packet = packet;
}

int
QUICUnknownFrame::debug_msg(char *msg, size_t msg_len) const
{
  return 0;
}

//
// QUICFrameFactory
//

QUICFrame *
QUICFrameFactory::create(uint8_t *buf, const uint8_t *src, size_t len, const QUICPacketR *packet)
{
  switch (QUICFrame::type(src)) {
  case QUICFrameType::STREAM:
    new (buf) QUICStreamFrame(src, len, packet);
    return reinterpret_cast<QUICFrame *>(buf);
  case QUICFrameType::CRYPTO:
    new (buf) QUICCryptoFrame(src, len, packet);
    return reinterpret_cast<QUICFrame *>(buf);
  case QUICFrameType::ACK:
    new (buf) QUICAckFrame(src, len, packet);
    return reinterpret_cast<QUICFrame *>(buf);
  case QUICFrameType::PADDING:
    new (buf) QUICPaddingFrame(src, len, packet);
    return reinterpret_cast<QUICFrame *>(buf);
  case QUICFrameType::RESET_STREAM:
    new (buf) QUICRstStreamFrame(src, len, packet);
    return reinterpret_cast<QUICFrame *>(buf);
  case QUICFrameType::CONNECTION_CLOSE:
    new (buf) QUICConnectionCloseFrame(src, len, packet);
    return reinterpret_cast<QUICFrame *>(buf);
  case QUICFrameType::MAX_DATA:
    new (buf) QUICMaxDataFrame(src, len, packet);
    return reinterpret_cast<QUICFrame *>(buf);
  case QUICFrameType::MAX_STREAM_DATA:
    new (buf) QUICMaxStreamDataFrame(src, len, packet);
    return reinterpret_cast<QUICFrame *>(buf);
  case QUICFrameType::MAX_STREAMS:
    new (buf) QUICMaxStreamsFrame(src, len, packet);
    return reinterpret_cast<QUICFrame *>(buf);
  case QUICFrameType::PING:
    new (buf) QUICPingFrame(src, len, packet);
    return reinterpret_cast<QUICFrame *>(buf);
  case QUICFrameType::DATA_BLOCKED:
    new (buf) QUICDataBlockedFrame(src, len, packet);
    return reinterpret_cast<QUICFrame *>(buf);
  case QUICFrameType::STREAM_DATA_BLOCKED:
    new (buf) QUICStreamDataBlockedFrame(src, len, packet);
    return reinterpret_cast<QUICFrame *>(buf);
  case QUICFrameType::STREAMS_BLOCKED:
    new (buf) QUICStreamIdBlockedFrame(src, len, packet);
    return reinterpret_cast<QUICFrame *>(buf);
  case QUICFrameType::NEW_CONNECTION_ID:
    new (buf) QUICNewConnectionIdFrame(src, len, packet);
    return reinterpret_cast<QUICFrame *>(buf);
  case QUICFrameType::STOP_SENDING:
    new (buf) QUICStopSendingFrame(src, len, packet);
    return reinterpret_cast<QUICFrame *>(buf);
  case QUICFrameType::PATH_CHALLENGE:
    new (buf) QUICPathChallengeFrame(src, len, packet);
    return reinterpret_cast<QUICFrame *>(buf);
  case QUICFrameType::PATH_RESPONSE:
    new (buf) QUICPathResponseFrame(src, len, packet);
    return reinterpret_cast<QUICFrame *>(buf);
  case QUICFrameType::NEW_TOKEN:
    new (buf) QUICNewTokenFrame(src, len, packet);
    return reinterpret_cast<QUICFrame *>(buf);
  case QUICFrameType::RETIRE_CONNECTION_ID:
    new (buf) QUICRetireConnectionIdFrame(src, len, packet);
    return reinterpret_cast<QUICFrame *>(buf);
  case QUICFrameType::HANDSHAKE_DONE:
    new (buf) QUICHandshakeDoneFrame(src, len, packet);
    return reinterpret_cast<QUICFrame *>(buf);
  default:
    // Unknown frame
    Debug("quic_frame_factory", "Unknown frame type %x", src[0]);
    return nullptr;
  }
}

const QUICFrame &
QUICFrameFactory::fast_create(const uint8_t *buf, size_t len, const QUICPacketR *packet)
{
  if (QUICFrame::type(buf) == QUICFrameType::UNKNOWN) {
    return this->_unknown_frame;
  }

  ptrdiff_t type_index = static_cast<ptrdiff_t>(QUICFrame::type(buf));
  QUICFrame *frame     = this->_reusable_frames[type_index];

  if (frame == nullptr) {
    frame = QUICFrameFactory::create(this->_buf_for_fast_create + (type_index * QUICFrame::MAX_INSTANCE_SIZE), buf, len, packet);
    if (frame != nullptr) {
      this->_reusable_frames[static_cast<ptrdiff_t>(QUICFrame::type(buf))] = frame;
    }
  } else {
    frame->parse(buf, len, packet);
  }

  return *frame;
}

QUICStreamFrame *
QUICFrameFactory::create_stream_frame(uint8_t *buf, Ptr<IOBufferBlock> &block, QUICStreamId stream_id, QUICOffset offset, bool last,
                                      bool has_offset_field, bool has_length_field, QUICFrameId id, QUICFrameGenerator *owner)
{
  Ptr<IOBufferBlock> new_block = make_ptr<IOBufferBlock>(block->clone());
  new (buf) QUICStreamFrame(new_block, stream_id, offset, last, has_offset_field, has_length_field, id, owner);
  return reinterpret_cast<QUICStreamFrame *>(buf);
}

QUICCryptoFrame *
QUICFrameFactory::create_crypto_frame(uint8_t *buf, Ptr<IOBufferBlock> &block, QUICOffset offset, QUICFrameId id,
                                      QUICFrameGenerator *owner)
{
  Ptr<IOBufferBlock> new_block = make_ptr<IOBufferBlock>(block->clone());
  new (buf) QUICCryptoFrame(new_block, offset, id, owner);
  return reinterpret_cast<QUICCryptoFrame *>(buf);
}

QUICAckFrame *
QUICFrameFactory::create_ack_frame(uint8_t *buf, QUICPacketNumber largest_acknowledged, uint64_t ack_delay,
                                   uint64_t first_ack_block, QUICFrameId id, QUICFrameGenerator *owner)
{
  new (buf) QUICAckFrame(largest_acknowledged, ack_delay, first_ack_block, id, owner);
  return reinterpret_cast<QUICAckFrame *>(buf);
}

QUICConnectionCloseFrame *
QUICFrameFactory::create_connection_close_frame(uint8_t *buf, uint16_t error_code, QUICFrameType frame_type,
                                                uint16_t reason_phrase_length, const char *reason_phrase, QUICFrameId id,
                                                QUICFrameGenerator *owner)
{
  new (buf) QUICConnectionCloseFrame(error_code, frame_type, reason_phrase_length, reason_phrase, id, owner);
  return reinterpret_cast<QUICConnectionCloseFrame *>(buf);
}

QUICConnectionCloseFrame *
QUICFrameFactory::create_connection_close_frame(uint8_t *buf, QUICConnectionError &error, QUICFrameId id, QUICFrameGenerator *owner)
{
  ink_assert(error.cls == QUICErrorClass::TRANSPORT);
  if (error.msg) {
    return QUICFrameFactory::create_connection_close_frame(buf, error.code, error.frame_type(), strlen(error.msg), error.msg, id,
                                                           owner);
  } else {
    return QUICFrameFactory::create_connection_close_frame(buf, error.code, error.frame_type(), 0, nullptr, id, owner);
  }
}

QUICMaxDataFrame *
QUICFrameFactory::create_max_data_frame(uint8_t *buf, uint64_t maximum_data, QUICFrameId id, QUICFrameGenerator *owner)
{
  new (buf) QUICMaxDataFrame(maximum_data, id, owner);
  return reinterpret_cast<QUICMaxDataFrame *>(buf);
}
QUICMaxStreamDataFrame *
QUICFrameFactory::create_max_stream_data_frame(uint8_t *buf, QUICStreamId stream_id, uint64_t maximum_data, QUICFrameId id,
                                               QUICFrameGenerator *owner)
{
  new (buf) QUICMaxStreamDataFrame(stream_id, maximum_data, id, owner);
  return reinterpret_cast<QUICMaxStreamDataFrame *>(buf);
}

QUICMaxStreamsFrame *
QUICFrameFactory::create_max_streams_frame(uint8_t *buf, QUICStreamId maximum_streams, QUICFrameId id, QUICFrameGenerator *owner)
{
  new (buf) QUICMaxStreamsFrame(maximum_streams, id, owner);
  return reinterpret_cast<QUICMaxStreamsFrame *>(buf);
}

QUICPingFrame *
QUICFrameFactory::create_ping_frame(uint8_t *buf, QUICFrameId id, QUICFrameGenerator *owner)
{
  new (buf) QUICPingFrame(id, owner);
  return reinterpret_cast<QUICPingFrame *>(buf);
}

QUICPaddingFrame *
QUICFrameFactory::create_padding_frame(uint8_t *buf, size_t size, QUICFrameId id, QUICFrameGenerator *owner)
{
  new (buf) QUICPaddingFrame(size);
  return reinterpret_cast<QUICPaddingFrame *>(buf);
}

QUICPathChallengeFrame *
QUICFrameFactory::create_path_challenge_frame(uint8_t *buf, const uint8_t *data, QUICFrameId id, QUICFrameGenerator *owner)
{
  ats_unique_buf challenge_data = ats_unique_malloc(QUICPathChallengeFrame::DATA_LEN);
  memcpy(challenge_data.get(), data, QUICPathChallengeFrame::DATA_LEN);

  new (buf) QUICPathChallengeFrame(std::move(challenge_data), id, owner);
  return reinterpret_cast<QUICPathChallengeFrame *>(buf);
}

QUICPathResponseFrame *
QUICFrameFactory::create_path_response_frame(uint8_t *buf, const uint8_t *data, QUICFrameId id, QUICFrameGenerator *owner)
{
  ats_unique_buf response_data = ats_unique_malloc(QUICPathResponseFrame::DATA_LEN);
  memcpy(response_data.get(), data, QUICPathResponseFrame::DATA_LEN);

  new (buf) QUICPathResponseFrame(std::move(response_data), id, owner);
  return reinterpret_cast<QUICPathResponseFrame *>(buf);
}

QUICDataBlockedFrame *
QUICFrameFactory::create_data_blocked_frame(uint8_t *buf, QUICOffset offset, QUICFrameId id, QUICFrameGenerator *owner)
{
  new (buf) QUICDataBlockedFrame(offset, id, owner);
  return reinterpret_cast<QUICDataBlockedFrame *>(buf);
}

QUICStreamDataBlockedFrame *
QUICFrameFactory::create_stream_data_blocked_frame(uint8_t *buf, QUICStreamId stream_id, QUICOffset offset, QUICFrameId id,
                                                   QUICFrameGenerator *owner)
{
  new (buf) QUICStreamDataBlockedFrame(stream_id, offset, id, owner);
  return reinterpret_cast<QUICStreamDataBlockedFrame *>(buf);
}

QUICStreamIdBlockedFrame *
QUICFrameFactory::create_stream_id_blocked_frame(uint8_t *buf, QUICStreamId stream_id, QUICFrameId id, QUICFrameGenerator *owner)
{
  new (buf) QUICStreamIdBlockedFrame(stream_id, id, owner);
  return reinterpret_cast<QUICStreamIdBlockedFrame *>(buf);
}

QUICRstStreamFrame *
QUICFrameFactory::create_rst_stream_frame(uint8_t *buf, QUICStreamId stream_id, QUICAppErrorCode error_code,
                                          QUICOffset final_offset, QUICFrameId id, QUICFrameGenerator *owner)
{
  new (buf) QUICRstStreamFrame(stream_id, error_code, final_offset, id, owner);
  return reinterpret_cast<QUICRstStreamFrame *>(buf);
}

QUICRstStreamFrame *
QUICFrameFactory::create_rst_stream_frame(uint8_t *buf, QUICStreamError &error, QUICFrameId id, QUICFrameGenerator *owner)
{
  return QUICFrameFactory::create_rst_stream_frame(buf, error.stream->id(), error.code, error.stream->final_offset(), id, owner);
}

QUICStopSendingFrame *
QUICFrameFactory::create_stop_sending_frame(uint8_t *buf, QUICStreamId stream_id, QUICAppErrorCode error_code, QUICFrameId id,
                                            QUICFrameGenerator *owner)
{
  new (buf) QUICStopSendingFrame(stream_id, error_code, id, owner);
  return reinterpret_cast<QUICStopSendingFrame *>(buf);
}

QUICNewConnectionIdFrame *
QUICFrameFactory::create_new_connection_id_frame(uint8_t *buf, uint64_t sequence, uint64_t retire_prior_to,
                                                 QUICConnectionId connection_id, QUICStatelessResetToken stateless_reset_token,
                                                 QUICFrameId id, QUICFrameGenerator *owner)
{
  new (buf) QUICNewConnectionIdFrame(sequence, retire_prior_to, connection_id, stateless_reset_token, id, owner);
  return reinterpret_cast<QUICNewConnectionIdFrame *>(buf);
}

QUICNewTokenFrame *
QUICFrameFactory::create_new_token_frame(uint8_t *buf, const QUICResumptionToken &token, QUICFrameId id, QUICFrameGenerator *owner)
{
  uint64_t token_len       = token.length();
  ats_unique_buf token_buf = ats_unique_malloc(token_len);
  memcpy(token_buf.get(), token.buf(), token_len);

  new (buf) QUICNewTokenFrame(std::move(token_buf), token_len, id, owner);
  return reinterpret_cast<QUICNewTokenFrame *>(buf);
}

QUICRetireConnectionIdFrame *
QUICFrameFactory::create_retire_connection_id_frame(uint8_t *buf, uint64_t seq_num, QUICFrameId id, QUICFrameGenerator *owner)
{
  new (buf) QUICRetireConnectionIdFrame(seq_num, id, owner);
  return reinterpret_cast<QUICRetireConnectionIdFrame *>(buf);
}

QUICHandshakeDoneFrame *
QUICFrameFactory::create_handshake_done_frame(uint8_t *buf, QUICFrameId id, QUICFrameGenerator *owner)
{
  new (buf) QUICHandshakeDoneFrame(id, owner);
  return reinterpret_cast<QUICHandshakeDoneFrame *>(buf);
}

QUICFrameId
QUICFrameInfo::id() const
{
  return this->_id;
}

QUICFrameGenerator *
QUICFrameInfo::generated_by() const
{
  return this->_generator;
}
