// Copyright (c) 2021 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/http/capsule.h"

#include <type_traits>

#include "absl/strings/escaping.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "quic/core/http/http_frames.h"
#include "quic/core/quic_data_reader.h"
#include "quic/core/quic_data_writer.h"
#include "quic/core/quic_types.h"
#include "quic/platform/api/quic_bug_tracker.h"
#include "common/platform/api/quiche_logging.h"

namespace quic {

std::string CapsuleTypeToString(CapsuleType capsule_type) {
  switch (capsule_type) {
    case CapsuleType::REGISTER_DATAGRAM_CONTEXT:
      return "REGISTER_DATAGRAM_CONTEXT";
    case CapsuleType::CLOSE_DATAGRAM_CONTEXT:
      return "CLOSE_DATAGRAM_CONTEXT";
    case CapsuleType::LEGACY_DATAGRAM:
      return "LEGACY_DATAGRAM";
    case CapsuleType::DATAGRAM_WITH_CONTEXT:
      return "DATAGRAM_WITH_CONTEXT";
    case CapsuleType::DATAGRAM_WITHOUT_CONTEXT:
      return "DATAGRAM_WITHOUT_CONTEXT";
    case CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT:
      return "REGISTER_DATAGRAM_NO_CONTEXT";
    case CapsuleType::CLOSE_WEBTRANSPORT_SESSION:
      return "CLOSE_WEBTRANSPORT_SESSION";
  }
  return absl::StrCat("Unknown(", static_cast<uint64_t>(capsule_type), ")");
}

std::ostream& operator<<(std::ostream& os, const CapsuleType& capsule_type) {
  os << CapsuleTypeToString(capsule_type);
  return os;
}

std::string DatagramFormatTypeToString(
    DatagramFormatType datagram_format_type) {
  switch (datagram_format_type) {
    case DatagramFormatType::UDP_PAYLOAD:
      return "UDP_PAYLOAD";
    case DatagramFormatType::WEBTRANSPORT:
      return "WEBTRANSPORT";
  }
  return absl::StrCat("Unknown(", static_cast<uint64_t>(datagram_format_type),
                      ")");
}

std::ostream& operator<<(std::ostream& os,
                         const DatagramFormatType& datagram_format_type) {
  os << DatagramFormatTypeToString(datagram_format_type);
  return os;
}

std::string ContextCloseCodeToString(ContextCloseCode context_close_code) {
  switch (context_close_code) {
    case ContextCloseCode::CLOSE_NO_ERROR:
      return "NO_ERROR";
    case ContextCloseCode::UNKNOWN_FORMAT:
      return "UNKNOWN_FORMAT";
    case ContextCloseCode::DENIED:
      return "DENIED";
    case ContextCloseCode::RESOURCE_LIMIT:
      return "RESOURCE_LIMIT";
  }
  return absl::StrCat("Unknown(", static_cast<uint64_t>(context_close_code),
                      ")");
}

std::ostream& operator<<(std::ostream& os,
                         const ContextCloseCode& context_close_code) {
  os << ContextCloseCodeToString(context_close_code);
  return os;
}

Capsule::Capsule(CapsuleType capsule_type) : capsule_type_(capsule_type) {
  switch (capsule_type) {
    case CapsuleType::LEGACY_DATAGRAM:
      static_assert(
          std::is_standard_layout<LegacyDatagramCapsule>::value &&
              std::is_trivially_destructible<LegacyDatagramCapsule>::value,
          "All capsule structs must have these properties");
      legacy_datagram_capsule_ = LegacyDatagramCapsule();
      break;
    case CapsuleType::DATAGRAM_WITH_CONTEXT:
      static_assert(
          std::is_standard_layout<DatagramWithContextCapsule>::value &&
              std::is_trivially_destructible<DatagramWithContextCapsule>::value,
          "All capsule structs must have these properties");
      datagram_with_context_capsule_ = DatagramWithContextCapsule();
      break;
    case CapsuleType::DATAGRAM_WITHOUT_CONTEXT:
      static_assert(
          std::is_standard_layout<DatagramWithoutContextCapsule>::value &&
              std::is_trivially_destructible<
                  DatagramWithoutContextCapsule>::value,
          "All capsule structs must have these properties");
      datagram_without_context_capsule_ = DatagramWithoutContextCapsule();
      break;
    case CapsuleType::REGISTER_DATAGRAM_CONTEXT:
      static_assert(
          std::is_standard_layout<RegisterDatagramContextCapsule>::value &&
              std::is_trivially_destructible<
                  RegisterDatagramContextCapsule>::value,
          "All capsule structs must have these properties");
      register_datagram_context_capsule_ = RegisterDatagramContextCapsule();
      break;
    case CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT:
      static_assert(
          std::is_standard_layout<RegisterDatagramNoContextCapsule>::value &&
              std::is_trivially_destructible<
                  RegisterDatagramNoContextCapsule>::value,
          "All capsule structs must have these properties");
      register_datagram_no_context_capsule_ =
          RegisterDatagramNoContextCapsule();
      break;
    case CapsuleType::CLOSE_DATAGRAM_CONTEXT:
      static_assert(
          std::is_standard_layout<CloseDatagramContextCapsule>::value &&
              std::is_trivially_destructible<
                  CloseDatagramContextCapsule>::value,
          "All capsule structs must have these properties");
      close_datagram_context_capsule_ = CloseDatagramContextCapsule();
      break;
    case CapsuleType::CLOSE_WEBTRANSPORT_SESSION:
      static_assert(
          std::is_standard_layout<CloseWebTransportSessionCapsule>::value &&
              std::is_trivially_destructible<
                  CloseWebTransportSessionCapsule>::value,
          "All capsule structs must have these properties");
      close_web_transport_session_capsule_ = CloseWebTransportSessionCapsule();
      break;
    default:
      unknown_capsule_data_ = absl::string_view();
      break;
  }
}

// static
Capsule Capsule::LegacyDatagram(
    absl::optional<QuicDatagramContextId> context_id,
    absl::string_view http_datagram_payload) {
  Capsule capsule(CapsuleType::LEGACY_DATAGRAM);
  capsule.legacy_datagram_capsule().context_id = context_id;
  capsule.legacy_datagram_capsule().http_datagram_payload =
      http_datagram_payload;
  return capsule;
}

// static
Capsule Capsule::DatagramWithContext(QuicDatagramContextId context_id,
                                     absl::string_view http_datagram_payload) {
  Capsule capsule(CapsuleType::DATAGRAM_WITH_CONTEXT);
  capsule.datagram_with_context_capsule().context_id = context_id;
  capsule.datagram_with_context_capsule().http_datagram_payload =
      http_datagram_payload;
  return capsule;
}

// static
Capsule Capsule::DatagramWithoutContext(
    absl::string_view http_datagram_payload) {
  Capsule capsule(CapsuleType::DATAGRAM_WITHOUT_CONTEXT);
  capsule.datagram_without_context_capsule().http_datagram_payload =
      http_datagram_payload;
  return capsule;
}

// static
Capsule Capsule::RegisterDatagramContext(
    QuicDatagramContextId context_id, DatagramFormatType format_type,
    absl::string_view format_additional_data) {
  Capsule capsule(CapsuleType::REGISTER_DATAGRAM_CONTEXT);
  capsule.register_datagram_context_capsule().context_id = context_id;
  capsule.register_datagram_context_capsule().format_type = format_type;
  capsule.register_datagram_context_capsule().format_additional_data =
      format_additional_data;
  return capsule;
}

// static
Capsule Capsule::RegisterDatagramNoContext(
    DatagramFormatType format_type, absl::string_view format_additional_data) {
  Capsule capsule(CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT);
  capsule.register_datagram_no_context_capsule().format_type = format_type;
  capsule.register_datagram_no_context_capsule().format_additional_data =
      format_additional_data;
  return capsule;
}

// static
Capsule Capsule::CloseDatagramContext(QuicDatagramContextId context_id,
                                      ContextCloseCode close_code,
                                      absl::string_view close_details) {
  Capsule capsule(CapsuleType::CLOSE_DATAGRAM_CONTEXT);
  capsule.close_datagram_context_capsule().context_id = context_id;
  capsule.close_datagram_context_capsule().close_code = close_code;
  capsule.close_datagram_context_capsule().close_details = close_details;
  return capsule;
}

// static
Capsule Capsule::CloseWebTransportSession(WebTransportSessionError error_code,
                                          absl::string_view error_message) {
  Capsule capsule(CapsuleType::CLOSE_WEBTRANSPORT_SESSION);
  capsule.close_web_transport_session_capsule().error_code = error_code;
  capsule.close_web_transport_session_capsule().error_message = error_message;
  return capsule;
}

// static
Capsule Capsule::Unknown(uint64_t capsule_type,
                         absl::string_view unknown_capsule_data) {
  Capsule capsule(static_cast<CapsuleType>(capsule_type));
  capsule.unknown_capsule_data() = unknown_capsule_data;
  return capsule;
}

Capsule& Capsule::operator=(const Capsule& other) {
  capsule_type_ = other.capsule_type_;
  switch (capsule_type_) {
    case CapsuleType::LEGACY_DATAGRAM:
      legacy_datagram_capsule_ = other.legacy_datagram_capsule_;
      break;
    case CapsuleType::DATAGRAM_WITH_CONTEXT:
      datagram_with_context_capsule_ = other.datagram_with_context_capsule_;
      break;
    case CapsuleType::DATAGRAM_WITHOUT_CONTEXT:
      datagram_without_context_capsule_ =
          other.datagram_without_context_capsule_;
      break;
    case CapsuleType::REGISTER_DATAGRAM_CONTEXT:
      register_datagram_context_capsule_ =
          other.register_datagram_context_capsule_;
      break;
    case CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT:
      register_datagram_no_context_capsule_ =
          other.register_datagram_no_context_capsule_;
      break;
    case CapsuleType::CLOSE_DATAGRAM_CONTEXT:
      close_datagram_context_capsule_ = other.close_datagram_context_capsule_;
      break;
    case CapsuleType::CLOSE_WEBTRANSPORT_SESSION:
      close_web_transport_session_capsule_ =
          other.close_web_transport_session_capsule_;
      break;
    default:
      unknown_capsule_data_ = other.unknown_capsule_data_;
      break;
  }
  return *this;
}

Capsule::Capsule(const Capsule& other) : Capsule(other.capsule_type_) {
  *this = other;
}

bool Capsule::operator==(const Capsule& other) const {
  if (capsule_type_ != other.capsule_type_) {
    return false;
  }
  switch (capsule_type_) {
    case CapsuleType::LEGACY_DATAGRAM:
      return legacy_datagram_capsule_.context_id ==
                 other.legacy_datagram_capsule_.context_id &&
             legacy_datagram_capsule_.http_datagram_payload ==
                 other.legacy_datagram_capsule_.http_datagram_payload;
    case CapsuleType::DATAGRAM_WITH_CONTEXT:
      return datagram_with_context_capsule_.context_id ==
                 other.datagram_with_context_capsule_.context_id &&
             datagram_with_context_capsule_.http_datagram_payload ==
                 other.datagram_with_context_capsule_.http_datagram_payload;
    case CapsuleType::DATAGRAM_WITHOUT_CONTEXT:
      return datagram_without_context_capsule_.http_datagram_payload ==
             other.datagram_without_context_capsule_.http_datagram_payload;
    case CapsuleType::REGISTER_DATAGRAM_CONTEXT:
      return register_datagram_context_capsule_.context_id ==
                 other.register_datagram_context_capsule_.context_id &&
             register_datagram_context_capsule_.format_type ==
                 other.register_datagram_context_capsule_.format_type &&
             register_datagram_context_capsule_.format_additional_data ==
                 other.register_datagram_context_capsule_
                     .format_additional_data;
    case CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT:
      return register_datagram_no_context_capsule_.format_type ==
                 other.register_datagram_no_context_capsule_.format_type &&
             register_datagram_no_context_capsule_.format_additional_data ==
                 other.register_datagram_no_context_capsule_
                     .format_additional_data;
    case CapsuleType::CLOSE_DATAGRAM_CONTEXT:
      return close_datagram_context_capsule_.context_id ==
                 other.close_datagram_context_capsule_.context_id &&
             close_datagram_context_capsule_.close_code ==
                 other.close_datagram_context_capsule_.close_code &&
             close_datagram_context_capsule_.close_details ==
                 other.close_datagram_context_capsule_.close_details;
    case CapsuleType::CLOSE_WEBTRANSPORT_SESSION:
      return close_web_transport_session_capsule_.error_code ==
                 other.close_web_transport_session_capsule_.error_code &&
             close_web_transport_session_capsule_.error_message ==
                 other.close_web_transport_session_capsule_.error_message;
    default:
      return unknown_capsule_data_ == other.unknown_capsule_data_;
  }
}

std::string Capsule::ToString() const {
  std::string rv = CapsuleTypeToString(capsule_type_);
  switch (capsule_type_) {
    case CapsuleType::LEGACY_DATAGRAM:
      if (legacy_datagram_capsule_.context_id.has_value()) {
        absl::StrAppend(&rv, "(", legacy_datagram_capsule_.context_id.value(),
                        ")");
      }
      absl::StrAppend(&rv, "[",
                      absl::BytesToHexString(
                          legacy_datagram_capsule_.http_datagram_payload),
                      "]");
      break;
    case CapsuleType::DATAGRAM_WITH_CONTEXT:
      absl::StrAppend(&rv, "(", datagram_with_context_capsule_.context_id, ")[",
                      absl::BytesToHexString(
                          datagram_with_context_capsule_.http_datagram_payload),
                      "]");
      break;
    case CapsuleType::DATAGRAM_WITHOUT_CONTEXT:
      absl::StrAppend(
          &rv, "[",
          absl::BytesToHexString(
              datagram_without_context_capsule_.http_datagram_payload),
          "]");
      break;
    case CapsuleType::REGISTER_DATAGRAM_CONTEXT:
      absl::StrAppend(
          &rv, "(context_id=", register_datagram_context_capsule_.context_id,
          ",format_type=",
          DatagramFormatTypeToString(
              register_datagram_context_capsule_.format_type),
          "){",
          absl::BytesToHexString(
              register_datagram_context_capsule_.format_additional_data),
          "}");
      break;
    case CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT:
      absl::StrAppend(
          &rv, "(format_type=",
          DatagramFormatTypeToString(
              register_datagram_no_context_capsule_.format_type),
          "){",
          absl::BytesToHexString(
              register_datagram_no_context_capsule_.format_additional_data),
          "}");
      break;
    case CapsuleType::CLOSE_DATAGRAM_CONTEXT:
      absl::StrAppend(
          &rv, "(context_id=", close_datagram_context_capsule_.context_id,
          ",close_code=",
          ContextCloseCodeToString(close_datagram_context_capsule_.close_code),
          ",close_details=\"",
          absl::BytesToHexString(close_datagram_context_capsule_.close_details),
          "\")");
      break;
    case CapsuleType::CLOSE_WEBTRANSPORT_SESSION:
      absl::StrAppend(
          &rv, "(error_code=", close_web_transport_session_capsule_.error_code,
          ",error_message=\"",
          close_web_transport_session_capsule_.error_message, "\")");
      break;
    default:
      absl::StrAppend(&rv, "[", absl::BytesToHexString(unknown_capsule_data_),
                      "]");
      break;
  }
  return rv;
}

std::ostream& operator<<(std::ostream& os, const Capsule& capsule) {
  os << capsule.ToString();
  return os;
}

CapsuleParser::CapsuleParser(Visitor* visitor) : visitor_(visitor) {
  QUICHE_DCHECK_NE(visitor_, nullptr);
}

QuicBuffer SerializeCapsule(const Capsule& capsule,
                            QuicBufferAllocator* allocator) {
  QuicByteCount capsule_type_length = QuicDataWriter::GetVarInt62Len(
      static_cast<uint64_t>(capsule.capsule_type()));
  QuicByteCount capsule_data_length;
  switch (capsule.capsule_type()) {
    case CapsuleType::LEGACY_DATAGRAM:
      capsule_data_length =
          capsule.legacy_datagram_capsule().http_datagram_payload.length();
      if (capsule.legacy_datagram_capsule().context_id.has_value()) {
        capsule_data_length += QuicDataWriter::GetVarInt62Len(
            capsule.legacy_datagram_capsule().context_id.value());
      }
      break;
    case CapsuleType::DATAGRAM_WITH_CONTEXT:
      capsule_data_length =
          QuicDataWriter::GetVarInt62Len(
              capsule.datagram_with_context_capsule().context_id) +
          capsule.datagram_with_context_capsule()
              .http_datagram_payload.length();
      break;
    case CapsuleType::DATAGRAM_WITHOUT_CONTEXT:
      capsule_data_length = capsule.datagram_without_context_capsule()
                                .http_datagram_payload.length();
      break;
    case CapsuleType::REGISTER_DATAGRAM_CONTEXT:
      capsule_data_length =
          QuicDataWriter::GetVarInt62Len(
              capsule.register_datagram_context_capsule().context_id) +
          QuicDataWriter::GetVarInt62Len(static_cast<uint64_t>(
              capsule.register_datagram_context_capsule().format_type)) +
          capsule.register_datagram_context_capsule()
              .format_additional_data.length();
      break;
    case CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT:
      capsule_data_length =
          QuicDataWriter::GetVarInt62Len(static_cast<uint64_t>(
              capsule.register_datagram_no_context_capsule().format_type)) +
          capsule.register_datagram_no_context_capsule()
              .format_additional_data.length();
      break;
    case CapsuleType::CLOSE_DATAGRAM_CONTEXT:
      capsule_data_length =
          QuicDataWriter::GetVarInt62Len(
              capsule.close_datagram_context_capsule().context_id) +
          QuicDataWriter::GetVarInt62Len(static_cast<uint64_t>(
              capsule.close_datagram_context_capsule().close_code)) +
          capsule.close_datagram_context_capsule().close_details.length();
      break;
    case CapsuleType::CLOSE_WEBTRANSPORT_SESSION:
      capsule_data_length =
          sizeof(WebTransportSessionError) +
          capsule.close_web_transport_session_capsule().error_message.size();
      break;
    default:
      capsule_data_length = capsule.unknown_capsule_data().length();
      break;
  }
  QuicByteCount capsule_length_length =
      QuicDataWriter::GetVarInt62Len(capsule_data_length);
  QuicByteCount total_capsule_length =
      capsule_type_length + capsule_length_length + capsule_data_length;
  QuicBuffer buffer(allocator, total_capsule_length);
  QuicDataWriter writer(buffer.size(), buffer.data());
  if (!writer.WriteVarInt62(static_cast<uint64_t>(capsule.capsule_type()))) {
    QUIC_BUG(capsule type write fail) << "Failed to write CAPSULE type";
    return QuicBuffer();
  }
  if (!writer.WriteVarInt62(capsule_data_length)) {
    QUIC_BUG(capsule length write fail) << "Failed to write CAPSULE length";
    return QuicBuffer();
  }
  switch (capsule.capsule_type()) {
    case CapsuleType::LEGACY_DATAGRAM:
      if (capsule.legacy_datagram_capsule().context_id.has_value()) {
        if (!writer.WriteVarInt62(
                capsule.legacy_datagram_capsule().context_id.value())) {
          QUIC_BUG(datagram capsule context ID write fail)
              << "Failed to write LEGACY_DATAGRAM CAPSULE context ID";
          return QuicBuffer();
        }
      }
      if (!writer.WriteStringPiece(
              capsule.legacy_datagram_capsule().http_datagram_payload)) {
        QUIC_BUG(datagram capsule payload write fail)
            << "Failed to write LEGACY_DATAGRAM CAPSULE payload";
        return QuicBuffer();
      }
      break;
    case CapsuleType::DATAGRAM_WITH_CONTEXT:
      if (!writer.WriteVarInt62(
              capsule.datagram_with_context_capsule().context_id)) {
        QUIC_BUG(datagram capsule context ID write fail)
            << "Failed to write DATAGRAM_WITH_CONTEXT CAPSULE context ID";
        return QuicBuffer();
      }
      if (!writer.WriteStringPiece(
              capsule.datagram_with_context_capsule().http_datagram_payload)) {
        QUIC_BUG(datagram capsule payload write fail)
            << "Failed to write DATAGRAM_WITH_CONTEXT CAPSULE payload";
        return QuicBuffer();
      }
      break;
    case CapsuleType::DATAGRAM_WITHOUT_CONTEXT:
      if (!writer.WriteStringPiece(capsule.datagram_without_context_capsule()
                                       .http_datagram_payload)) {
        QUIC_BUG(datagram capsule payload write fail)
            << "Failed to write DATAGRAM_WITHOUT_CONTEXT CAPSULE payload";
        return QuicBuffer();
      }
      break;
    case CapsuleType::REGISTER_DATAGRAM_CONTEXT:
      if (!writer.WriteVarInt62(
              capsule.register_datagram_context_capsule().context_id)) {
        QUIC_BUG(register context capsule context ID write fail)
            << "Failed to write REGISTER_DATAGRAM_CONTEXT CAPSULE context ID";
        return QuicBuffer();
      }
      if (!writer.WriteVarInt62(static_cast<uint64_t>(
              capsule.register_datagram_context_capsule().format_type))) {
        QUIC_BUG(register context capsule format type write fail)
            << "Failed to write REGISTER_DATAGRAM_CONTEXT CAPSULE format type";
        return QuicBuffer();
      }
      if (!writer.WriteStringPiece(capsule.register_datagram_context_capsule()
                                       .format_additional_data)) {
        QUIC_BUG(register context capsule additional data write fail)
            << "Failed to write REGISTER_DATAGRAM_CONTEXT CAPSULE additional "
               "data";
        return QuicBuffer();
      }
      break;
    case CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT:
      if (!writer.WriteVarInt62(static_cast<uint64_t>(
              capsule.register_datagram_no_context_capsule().format_type))) {
        QUIC_BUG(register no context capsule format type write fail)
            << "Failed to write REGISTER_DATAGRAM_NO_CONTEXT CAPSULE format "
               "type";
        return QuicBuffer();
      }
      if (!writer.WriteStringPiece(
              capsule.register_datagram_no_context_capsule()
                  .format_additional_data)) {
        QUIC_BUG(register no context capsule additional data write fail)
            << "Failed to write REGISTER_DATAGRAM_NO_CONTEXT CAPSULE "
               "additional data";
        return QuicBuffer();
      }
      break;
    case CapsuleType::CLOSE_DATAGRAM_CONTEXT:
      if (!writer.WriteVarInt62(
              capsule.close_datagram_context_capsule().context_id)) {
        QUIC_BUG(close context capsule context ID write fail)
            << "Failed to write CLOSE_DATAGRAM_CONTEXT CAPSULE context ID";
        return QuicBuffer();
      }
      if (!writer.WriteVarInt62(static_cast<uint64_t>(
              capsule.close_datagram_context_capsule().close_code))) {
        QUIC_BUG(close context capsule close code write fail)
            << "Failed to write CLOSE_DATAGRAM_CONTEXT CAPSULE close code";
        return QuicBuffer();
      }
      if (!writer.WriteStringPiece(
              capsule.close_datagram_context_capsule().close_details)) {
        QUIC_BUG(close context capsule close details write fail)
            << "Failed to write CLOSE_DATAGRAM_CONTEXT CAPSULE close details";
        return QuicBuffer();
      }
      break;
    case CapsuleType::CLOSE_WEBTRANSPORT_SESSION:
      if (!writer.WriteUInt32(
              capsule.close_web_transport_session_capsule().error_code)) {
        QUIC_BUG(close webtransport session capsule error code write fail)
            << "Failed to write CLOSE_WEBTRANSPORT_SESSION error code";
        return QuicBuffer();
      }
      if (!writer.WriteStringPiece(
              capsule.close_web_transport_session_capsule().error_message)) {
        QUIC_BUG(close webtransport session capsule error message write fail)
            << "Failed to write CLOSE_WEBTRANSPORT_SESSION error message";
        return QuicBuffer();
      }
      break;
    default:
      if (!writer.WriteStringPiece(capsule.unknown_capsule_data())) {
        QUIC_BUG(capsule data write fail) << "Failed to write CAPSULE data";
        return QuicBuffer();
      }
      break;
  }
  if (writer.remaining() != 0) {
    QUIC_BUG(capsule write length mismatch)
        << "CAPSULE serialization wrote " << writer.length() << " instead of "
        << writer.capacity();
    return QuicBuffer();
  }
  return buffer;
}

bool CapsuleParser::IngestCapsuleFragment(absl::string_view capsule_fragment) {
  if (parsing_error_occurred_) {
    return false;
  }
  absl::StrAppend(&buffered_data_, capsule_fragment);
  while (true) {
    const size_t buffered_data_read = AttemptParseCapsule();
    if (parsing_error_occurred_) {
      QUICHE_DCHECK_EQ(buffered_data_read, 0u);
      buffered_data_.clear();
      return false;
    }
    if (buffered_data_read == 0) {
      break;
    }
    buffered_data_.erase(0, buffered_data_read);
  }
  static constexpr size_t kMaxCapsuleBufferSize = 1024 * 1024;
  if (buffered_data_.size() > kMaxCapsuleBufferSize) {
    buffered_data_.clear();
    ReportParseFailure("Refusing to buffer too much capsule data");
    return false;
  }
  return true;
}

size_t CapsuleParser::AttemptParseCapsule() {
  QUICHE_DCHECK(!parsing_error_occurred_);
  if (buffered_data_.empty()) {
    return 0;
  }
  QuicDataReader capsule_fragment_reader(buffered_data_);
  uint64_t capsule_type64;
  if (!capsule_fragment_reader.ReadVarInt62(&capsule_type64)) {
    QUIC_DVLOG(2) << "Partial read: not enough data to read capsule type";
    return 0;
  }
  absl::string_view capsule_data;
  if (!capsule_fragment_reader.ReadStringPieceVarInt62(&capsule_data)) {
    QUIC_DVLOG(2) << "Partial read: not enough data to read capsule length or "
                     "full capsule data";
    return 0;
  }
  QuicDataReader capsule_data_reader(capsule_data);
  Capsule capsule(static_cast<CapsuleType>(capsule_type64));
  switch (capsule.capsule_type()) {
    case CapsuleType::LEGACY_DATAGRAM:
      if (datagram_context_id_present_) {
        uint64_t context_id;
        if (!capsule_data_reader.ReadVarInt62(&context_id)) {
          ReportParseFailure(
              "Unable to parse capsule LEGACY_DATAGRAM context ID");
          return 0;
        }
        capsule.legacy_datagram_capsule().context_id = context_id;
      }
      capsule.legacy_datagram_capsule().http_datagram_payload =
          capsule_data_reader.ReadRemainingPayload();
      break;
    case CapsuleType::DATAGRAM_WITH_CONTEXT:
      uint64_t context_id;
      if (!capsule_data_reader.ReadVarInt62(&context_id)) {
        ReportParseFailure(
            "Unable to parse capsule DATAGRAM_WITH_CONTEXT context ID");
        return 0;
      }
      capsule.datagram_with_context_capsule().context_id = context_id;
      capsule.datagram_with_context_capsule().http_datagram_payload =
          capsule_data_reader.ReadRemainingPayload();
      break;
    case CapsuleType::DATAGRAM_WITHOUT_CONTEXT:
      capsule.datagram_without_context_capsule().http_datagram_payload =
          capsule_data_reader.ReadRemainingPayload();
      break;
    case CapsuleType::REGISTER_DATAGRAM_CONTEXT:
      if (!capsule_data_reader.ReadVarInt62(
              &capsule.register_datagram_context_capsule().context_id)) {
        ReportParseFailure(
            "Unable to parse capsule REGISTER_DATAGRAM_CONTEXT context ID");
        return 0;
      }
      if (!capsule_data_reader.ReadVarInt62(reinterpret_cast<uint64_t*>(
              &capsule.register_datagram_context_capsule().format_type))) {
        ReportParseFailure(
            "Unable to parse capsule REGISTER_DATAGRAM_CONTEXT format type");
        return 0;
      }
      capsule.register_datagram_context_capsule().format_additional_data =
          capsule_data_reader.ReadRemainingPayload();
      break;
    case CapsuleType::REGISTER_DATAGRAM_NO_CONTEXT:
      if (!capsule_data_reader.ReadVarInt62(reinterpret_cast<uint64_t*>(
              &capsule.register_datagram_no_context_capsule().format_type))) {
        ReportParseFailure(
            "Unable to parse capsule REGISTER_DATAGRAM_NO_CONTEXT format type");
        return 0;
      }
      capsule.register_datagram_no_context_capsule().format_additional_data =
          capsule_data_reader.ReadRemainingPayload();
      break;
    case CapsuleType::CLOSE_DATAGRAM_CONTEXT:
      if (!capsule_data_reader.ReadVarInt62(
              &capsule.close_datagram_context_capsule().context_id)) {
        ReportParseFailure(
            "Unable to parse capsule CLOSE_DATAGRAM_CONTEXT context ID");
        return 0;
      }
      if (!capsule_data_reader.ReadVarInt62(reinterpret_cast<uint64_t*>(
              &capsule.close_datagram_context_capsule().close_code))) {
        ReportParseFailure(
            "Unable to parse capsule CLOSE_DATAGRAM_CONTEXT close code");
        return 0;
      }
      capsule.close_datagram_context_capsule().close_details =
          capsule_data_reader.ReadRemainingPayload();
      break;
    case CapsuleType::CLOSE_WEBTRANSPORT_SESSION:
      if (!capsule_data_reader.ReadUInt32(
              &capsule.close_web_transport_session_capsule().error_code)) {
        ReportParseFailure(
            "Unable to parse capsule CLOSE_WEBTRANSPORT_SESSION error code");
        return 0;
      }
      capsule.close_web_transport_session_capsule().error_message =
          capsule_data_reader.ReadRemainingPayload();
      break;
    default:
      capsule.unknown_capsule_data() =
          capsule_data_reader.ReadRemainingPayload();
  }
  if (!visitor_->OnCapsule(capsule)) {
    ReportParseFailure("Visitor failed to process capsule");
    return 0;
  }
  return capsule_fragment_reader.PreviouslyReadPayload().length();
}

void CapsuleParser::ReportParseFailure(const std::string& error_message) {
  if (parsing_error_occurred_) {
    QUIC_BUG(multiple parse errors) << "Experienced multiple parse failures";
    return;
  }
  parsing_error_occurred_ = true;
  visitor_->OnCapsuleParseFailure(error_message);
}

void CapsuleParser::ErrorIfThereIsRemainingBufferedData() {
  if (parsing_error_occurred_) {
    return;
  }
  if (!buffered_data_.empty()) {
    ReportParseFailure("Incomplete capsule left at the end of the stream");
  }
}

}  // namespace quic
