#include "quiche/binary_http/binary_http_message.h"

#include <algorithm>
#include <cstddef>
#include <cstdint>
#include <optional>
#include <ostream>
#include <string>
#include <utility>
#include <vector>

#include "absl/base/attributes.h"
#include "absl/functional/bind_front.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/ascii.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_format.h"
#include "absl/strings/str_join.h"
#include "absl/strings/string_view.h"
#include "absl/types/span.h"
#include "quiche/common/platform/api/quiche_logging.h"
#include "quiche/common/quiche_callbacks.h"
#include "quiche/common/quiche_data_reader.h"
#include "quiche/common/quiche_data_writer.h"
#include "quiche/common/quiche_status_utils.h"

namespace quiche {
namespace {

constexpr uint64_t kKnownLengthRequestFraming = 0;
constexpr uint64_t kKnownLengthResponseFraming = 1;
constexpr uint64_t kIndeterminateLengthRequestFraming = 2;
constexpr uint64_t kIndeterminateLengthResponseFraming = 3;
constexpr uint64_t kContentTerminator = 0;
constexpr int kMinInformationalStatusCode = 100;
constexpr int kMaxInformationalStatusCode = 199;
constexpr int kMinFinalStatusCode = 200;
constexpr int kMaxFinalStatusCode = 599;

bool ReadStringValue(quiche::QuicheDataReader& reader, std::string& data) {
  absl::string_view data_view;
  if (!reader.ReadStringPieceVarInt62(&data_view)) {
    return false;
  }
  data = std::string(data_view);
  return true;
}

bool IsValidPadding(absl::string_view data) {
  return std::all_of(data.begin(), data.end(),
                     [](char c) { return c == '\0'; });
}

absl::StatusOr<BinaryHttpRequest::ControlData> DecodeControlData(
    quiche::QuicheDataReader& reader) {
  BinaryHttpRequest::ControlData control_data;
  if (!ReadStringValue(reader, control_data.method)) {
    return absl::InvalidArgumentError("Failed to read method.");
  }
  if (!ReadStringValue(reader, control_data.scheme)) {
    return absl::InvalidArgumentError("Failed to read scheme.");
  }
  if (!ReadStringValue(reader, control_data.authority)) {
    return absl::InvalidArgumentError("Failed to read authority.");
  }
  if (!ReadStringValue(reader, control_data.path)) {
    return absl::InvalidArgumentError("Failed to read path.");
  }
  return control_data;
}

// Decodes a header/trailer name and value. This takes a length which represents
// only the name length.
absl::StatusOr<BinaryHttpMessage::FieldView> DecodeField(
    QuicheDataReader& reader, uint64_t name_length) {
  absl::string_view name;
  if (!reader.ReadStringPiece(&name, name_length)) {
    return absl::OutOfRangeError("Not enough data to read field name.");
  }
  absl::string_view value;
  if (!reader.ReadStringPieceVarInt62(&value)) {
    return absl::OutOfRangeError("Not enough data to read field value.");
  }
  return BinaryHttpMessage::FieldView{name, value};
}

absl::Status DecodeFields(quiche::QuicheDataReader& reader,
                          quiche::UnretainedCallback<void(
                              absl::string_view name, absl::string_view value)>
                              callback) {
  absl::string_view fields;
  if (!reader.ReadStringPieceVarInt62(&fields)) {
    return absl::InvalidArgumentError("Failed to read fields.");
  }
  quiche::QuicheDataReader fields_reader(fields);
  while (!fields_reader.IsDoneReading()) {
    absl::string_view name;
    if (!fields_reader.ReadStringPieceVarInt62(&name)) {
      return absl::InvalidArgumentError("Failed to read field name.");
    }
    absl::string_view value;
    if (!fields_reader.ReadStringPieceVarInt62(&value)) {
      return absl::InvalidArgumentError("Failed to read field value.");
    }
    callback(name, value);
  }
  return absl::OkStatus();
}

absl::Status DecodeFieldsAndBody(quiche::QuicheDataReader& reader,
                                 BinaryHttpMessage& message) {
  if (const absl::Status status = DecodeFields(
          reader,
          [&message](absl::string_view name, absl::string_view value) {
            message.AddHeaderField({std::string(name), std::string(value)});
          });
      !status.ok()) {
    return status;
  }
  // Exit early if message has been truncated.
  // https://www.rfc-editor.org/rfc/rfc9292#section-3.8
  if (reader.IsDoneReading()) {
    return absl::OkStatus();
  }

  absl::string_view body;
  if (!reader.ReadStringPieceVarInt62(&body)) {
    return absl::InvalidArgumentError("Failed to read body.");
  }
  message.set_body(std::string(body));
  // TODO(bschneider): Check for / read-in any trailer-fields
  return absl::OkStatus();
}

absl::StatusOr<BinaryHttpRequest> DecodeKnownLengthRequest(
    quiche::QuicheDataReader& reader) {
  const auto control_data = DecodeControlData(reader);
  if (!control_data.ok()) {
    return control_data.status();
  }
  BinaryHttpRequest request(std::move(*control_data));
  if (reader.IsDoneReading()) {
    // Per RFC 9292, Section 3.8, "Decoders MUST treat missing truncated fields
    // as equivalent to having been sent with the length field set to zero."
    // If we've run out of payload, stop parsing and return the request.
    return request;
  }
  if (const absl::Status status = DecodeFieldsAndBody(reader, request);
      !status.ok()) {
    return status;
  }
  if (!IsValidPadding(reader.PeekRemainingPayload())) {
    return absl::InvalidArgumentError("Non-zero padding.");
  }
  request.set_num_padding_bytes(reader.BytesRemaining());
  return request;
}

absl::StatusOr<BinaryHttpResponse> DecodeKnownLengthResponse(
    quiche::QuicheDataReader& reader) {
  std::vector<std::pair<uint16_t, std::vector<BinaryHttpMessage::Field>>>
      informational_responses;
  uint64_t status_code;
  bool reading_response_control_data = true;
  while (reading_response_control_data) {
    if (!reader.ReadVarInt62(&status_code)) {
      return absl::InvalidArgumentError("Failed to read status code.");
    }
    if (status_code >= kMinInformationalStatusCode &&
        status_code <= kMaxInformationalStatusCode) {
      std::vector<BinaryHttpMessage::Field> fields;
      if (const absl::Status status = DecodeFields(
              reader,
              [&fields](absl::string_view name, absl::string_view value) {
                fields.push_back({std::string(name), std::string(value)});
              });
          !status.ok()) {
        return status;
      }
      informational_responses.emplace_back(status_code, std::move(fields));
    } else {
      reading_response_control_data = false;
    }
  }
  BinaryHttpResponse response(status_code);
  for (const auto& informational_response : informational_responses) {
    if (const absl::Status status = response.AddInformationalResponse(
            informational_response.first,
            std::move(informational_response.second));
        !status.ok()) {
      return status;
    }
  }
  if (const absl::Status status = DecodeFieldsAndBody(reader, response);
      !status.ok()) {
    return status;
  }
  if (!IsValidPadding(reader.PeekRemainingPayload())) {
    return absl::InvalidArgumentError("Non-zero padding.");
  }
  response.set_num_padding_bytes(reader.BytesRemaining());
  return response;
}

uint64_t StringPieceVarInt62Len(absl::string_view s) {
  return quiche::QuicheDataWriter::GetVarInt62Len(s.length()) + s.length();
}

absl::StatusOr<std::string> EncodeBodyChunksImpl(
    absl::Span<const absl::string_view> body_chunks, bool body_chunks_done) {
  uint64_t total_length = 0;
  for (const auto& body_chunk : body_chunks) {
    uint8_t body_chunk_var_int_length =
        QuicheDataWriter::GetVarInt62Len(body_chunk.size());
    if (body_chunk_var_int_length == 0) {
      return absl::InvalidArgumentError(
          "Body chunk size exceeds maximum length.");
    }
    total_length += body_chunk_var_int_length + body_chunk.size();
  }
  if (body_chunks_done) {
    total_length +=
        quiche::QuicheDataWriter::GetVarInt62Len(kContentTerminator);
  }

  std::string data(total_length, '\0');
  QuicheDataWriter writer(total_length, data.data());

  for (const auto& body_chunk : body_chunks) {
    if (!writer.WriteStringPieceVarInt62(body_chunk)) {
      return absl::InternalError("Failed to write body chunk.");
    }
  }
  if (body_chunks_done) {
    if (!writer.WriteVarInt62(kContentTerminator)) {
      return absl::InternalError("Failed to write content terminator.");
    }
  }

  if (writer.remaining() != 0) {
    return absl::InternalError("Failed to write all data.");
  }
  return data;
}

// Initializes the checkpoint based on the provided data and any buffered data.
// If the buffer has data, the new data is appended to the buffer.
absl::string_view InitializeChunkedDecodingCheckpoint(absl::string_view data,
                                                      std::string& buffer) {
  absl::string_view checkpoint = data;
  // Prepend buffered data if present.
  if (!buffer.empty()) {
    absl::StrAppend(&buffer, data);
    checkpoint = buffer;
  }
  return checkpoint;
}

// Updates the checkpoint based on the current position of the reader.
void UpdateChunkedDecodingCheckpoint(const QuicheDataReader& reader,
                                     absl::string_view& checkpoint) {
  checkpoint = reader.PeekRemainingPayload();
}

// Buffers the checkpoint.
void BufferChunkedDecodingCheckpoint(absl::string_view checkpoint,
                                     std::string& buffer) {
  if (buffer != checkpoint) {
    buffer.assign(checkpoint);
  }
}

// Decodes the fields in the reader. Calls the field_handler for each field
// until the reader is done or the content terminator is encountered.
absl::Status DecodeContentTerminatedFieldSection(
    QuicheDataReader& reader, absl::string_view& checkpoint,
    quiche::UnretainedCallback<absl::Status(absl::string_view,
                                            absl::string_view)>
        field_handler) {
  uint64_t length_or_content_terminator = kContentTerminator;
  do {
    if (!reader.ReadVarInt62(&length_or_content_terminator)) {
      return absl::OutOfRangeError("Not enough data to read section.");
    }
    if (length_or_content_terminator != kContentTerminator) {
      const absl::StatusOr<BinaryHttpMessage::FieldView> field =
          DecodeField(reader, length_or_content_terminator);
      if (!field.ok()) {
        return field.status();
      }
      const absl::Status section_status =
          field_handler(field->name, field->value);
      if (!section_status.ok()) {
        return absl::InternalError(absl::StrCat("Failed to handle header: ",
                                                section_status.message()));
      }
    }
    // Either a field was successfully decoded or a content terminator was
    // encountered, update the checkpoint.
    UpdateChunkedDecodingCheckpoint(reader, checkpoint);
  } while (length_or_content_terminator != kContentTerminator);
  return absl::OkStatus();
}

// Decodes the body chunks in the reader. Calls the body_chunk_handler for
// each body chunk until the reader is done or the content terminator is
// encountered.
absl::Status DecodeContentTerminatedBodyChunkSection(
    QuicheDataReader& reader, absl::string_view& checkpoint,
    quiche::UnretainedCallback<absl::Status(absl::string_view)>
        body_chunk_handler) {
  uint64_t length_or_content_terminator = kContentTerminator;
  do {
    if (!reader.ReadVarInt62(&length_or_content_terminator)) {
      return absl::OutOfRangeError("Not enough data to read section.");
    }
    if (length_or_content_terminator != kContentTerminator) {
      absl::string_view body_chunk;
      if (!reader.ReadStringPiece(&body_chunk, length_or_content_terminator)) {
        return absl::OutOfRangeError("Failed to read body chunk.");
      }
      const absl::Status section_status = body_chunk_handler(body_chunk);
      if (!section_status.ok()) {
        return absl::InternalError(absl::StrCat("Failed to handle body chunk: ",
                                                section_status.message()));
      }
    }
    // Either a body chunk was successfully decoded or a content terminator was
    // encountered, update the checkpoint.
    UpdateChunkedDecodingCheckpoint(reader, checkpoint);
  } while (length_or_content_terminator != kContentTerminator);
  return absl::OkStatus();
}

absl::StatusOr<uint64_t> GetFieldSectionLength(
    absl::Span<const BinaryHttpMessage::FieldView> fields) {
  uint64_t field_section_length = 0;
  for (const auto& field : fields) {
    uint8_t var_int_length =
        QuicheDataWriter::GetVarInt62Len(field.name.size());
    if (var_int_length == 0) {
      return absl::InvalidArgumentError("Field name exceeds maximum length.");
    }
    field_section_length += var_int_length + field.name.size();

    var_int_length = QuicheDataWriter::GetVarInt62Len(field.value.size());
    if (var_int_length == 0) {
      return absl::InvalidArgumentError("Field value exceeds maximum length.");
    }
    field_section_length += var_int_length + field.value.size();
  }
  field_section_length +=
      quiche::QuicheDataWriter::GetVarInt62Len(kContentTerminator);
  return field_section_length;
}

absl::Status EncodeFields(absl::Span<const BinaryHttpMessage::FieldView> fields,
                          quiche::QuicheDataWriter& writer) {
  for (const auto& field : fields) {
    if (!writer.WriteStringPieceVarInt62(absl::AsciiStrToLower(field.name))) {
      return absl::InternalError("Failed to write field name.");
    }
    if (!writer.WriteStringPieceVarInt62(field.value)) {
      return absl::InternalError("Failed to write field value.");
    }
  }
  if (!writer.WriteVarInt62(kContentTerminator)) {
    return absl::InternalError("Failed to write content terminator.");
  }
  return absl::OkStatus();
}

}  // namespace

void BinaryHttpMessage::Fields::AddField(BinaryHttpMessage::Field field) {
  fields_.push_back(std::move(field));
}

// Encode fields in the order they were initially inserted.
// Updates do not change order.
absl::Status BinaryHttpMessage::Fields::Encode(
    quiche::QuicheDataWriter& writer) const {
  if (!writer.WriteVarInt62(EncodedFieldsSize())) {
    return absl::InvalidArgumentError("Failed to write encoded field size.");
  }
  for (const BinaryHttpMessage::Field& field : fields_) {
    if (!writer.WriteStringPieceVarInt62(field.name)) {
      return absl::InvalidArgumentError("Failed to write field name.");
    }
    if (!writer.WriteStringPieceVarInt62(field.value)) {
      return absl::InvalidArgumentError("Failed to write field value.");
    }
  }
  return absl::OkStatus();
}

size_t BinaryHttpMessage::Fields::EncodedSize() const {
  const size_t size = EncodedFieldsSize();
  return size + quiche::QuicheDataWriter::GetVarInt62Len(size);
}

size_t BinaryHttpMessage::Fields::EncodedFieldsSize() const {
  size_t size = 0;
  for (const BinaryHttpMessage::Field& field : fields_) {
    size += StringPieceVarInt62Len(field.name) +
            StringPieceVarInt62Len(field.value);
  }
  return size;
}

BinaryHttpMessage* BinaryHttpMessage::AddHeaderField(
    BinaryHttpMessage::Field field) {
  const std::string lower_name = absl::AsciiStrToLower(field.name);
  if (lower_name == "host") {
    has_host_ = true;
  }
  header_fields_.AddField({std::move(lower_name), std::move(field.value)});
  return this;
}

// Appends the encoded fields and body to data.
absl::Status BinaryHttpMessage::EncodeKnownLengthFieldsAndBody(
    quiche::QuicheDataWriter& writer) const {
  if (const absl::Status status = header_fields_.Encode(writer); !status.ok()) {
    return status;
  }
  if (!writer.WriteStringPieceVarInt62(body_)) {
    return absl::InvalidArgumentError("Failed to encode body.");
  }
  // TODO(bschneider): Consider support for trailer fields on known-length
  // requests. Trailers are atypical for a known-length request.
  return absl::OkStatus();
}

size_t BinaryHttpMessage::EncodedKnownLengthFieldsAndBodySize() const {
  return header_fields_.EncodedSize() + StringPieceVarInt62Len(body_);
}

absl::Status BinaryHttpResponse::AddInformationalResponse(
    uint16_t status_code, std::vector<Field> header_fields) {
  if (status_code < kMinInformationalStatusCode) {
    return absl::InvalidArgumentError("status code < 100");
  } else if (status_code > kMaxInformationalStatusCode) {
    return absl::InvalidArgumentError("status code > 199");
  }
  InformationalResponse data(status_code);
  for (Field& header : header_fields) {
    data.AddField(header.name, std::move(header.value));
  }
  informational_response_control_data_.push_back(std::move(data));
  return absl::OkStatus();
}

absl::StatusOr<std::string> BinaryHttpResponse::Serialize() const {
  // Only supporting known length requests so far.
  return EncodeAsKnownLength();
}

absl::StatusOr<std::string> BinaryHttpResponse::EncodeAsKnownLength() const {
  std::string data;
  data.resize(EncodedSize());
  quiche::QuicheDataWriter writer(data.size(), data.data());
  if (!writer.WriteVarInt62(kKnownLengthResponseFraming)) {
    return absl::InvalidArgumentError("Failed to write framing indicator");
  }
  // Informational response
  for (const auto& informational : informational_response_control_data_) {
    if (const absl::Status status = informational.Encode(writer);
        !status.ok()) {
      return status;
    }
  }
  if (!writer.WriteVarInt62(status_code_)) {
    return absl::InvalidArgumentError("Failed to write status code");
  }
  if (const absl::Status status = EncodeKnownLengthFieldsAndBody(writer);
      !status.ok()) {
    return status;
  }
  QUICHE_DCHECK_EQ(writer.remaining(), num_padding_bytes());
  writer.WritePadding();
  return data;
}

size_t BinaryHttpResponse::EncodedSize() const {
  size_t size = QuicheDataWriter::GetVarInt62Len(kKnownLengthResponseFraming);
  for (const auto& informational : informational_response_control_data_) {
    size += informational.EncodedSize();
  }
  return size + quiche::QuicheDataWriter::GetVarInt62Len(status_code_) +
         EncodedKnownLengthFieldsAndBodySize() + num_padding_bytes();
}

void BinaryHttpResponse::InformationalResponse::AddField(absl::string_view name,
                                                         std::string value) {
  fields_.AddField({absl::AsciiStrToLower(name), std::move(value)});
}

// Appends the encoded fields and body to data.
absl::Status BinaryHttpResponse::InformationalResponse::Encode(
    quiche::QuicheDataWriter& writer) const {
  writer.WriteVarInt62(status_code_);
  return fields_.Encode(writer);
}

size_t BinaryHttpResponse::InformationalResponse::EncodedSize() const {
  return quiche::QuicheDataWriter::GetVarInt62Len(status_code_) +
         fields_.EncodedSize();
}

absl::StatusOr<std::string> BinaryHttpRequest::Serialize() const {
  // Only supporting known length requests so far.
  return EncodeAsKnownLength();
}

// https://www.ietf.org/archive/id/draft-ietf-httpbis-binary-message-06.html#name-request-control-data
absl::Status BinaryHttpRequest::EncodeControlData(
    quiche::QuicheDataWriter& writer) const {
  if (!writer.WriteStringPieceVarInt62(control_data_.method)) {
    return absl::InvalidArgumentError("Failed to encode method.");
  }
  if (!writer.WriteStringPieceVarInt62(control_data_.scheme)) {
    return absl::InvalidArgumentError("Failed to encode scheme.");
  }
  // the Host header field is not replicated in the :authority field, as is
  // required for ensuring that the request is reproduced accurately; see
  // Section 8.1.2.3 of [H2].
  if (!has_host()) {
    if (!writer.WriteStringPieceVarInt62(control_data_.authority)) {
      return absl::InvalidArgumentError("Failed to encode authority.");
    }
  } else {
    if (!writer.WriteStringPieceVarInt62("")) {
      return absl::InvalidArgumentError("Failed to encode authority.");
    }
  }
  if (!writer.WriteStringPieceVarInt62(control_data_.path)) {
    return absl::InvalidArgumentError("Failed to encode path.");
  }
  return absl::OkStatus();
}

size_t BinaryHttpRequest::EncodedControlDataSize() const {
  size_t size = StringPieceVarInt62Len(control_data_.method) +
                StringPieceVarInt62Len(control_data_.scheme) +
                StringPieceVarInt62Len(control_data_.path);
  if (!has_host()) {
    size += StringPieceVarInt62Len(control_data_.authority);
  } else {
    size += StringPieceVarInt62Len("");
  }
  return size;
}

size_t BinaryHttpRequest::EncodedSize() const {
  return QuicheDataWriter::GetVarInt62Len(kKnownLengthRequestFraming) +
         EncodedControlDataSize() + EncodedKnownLengthFieldsAndBodySize() +
         num_padding_bytes();
}

// https://www.ietf.org/archive/id/draft-ietf-httpbis-binary-message-06.html#name-known-length-messages
absl::StatusOr<std::string> BinaryHttpRequest::EncodeAsKnownLength() const {
  std::string data;
  data.resize(EncodedSize());
  quiche::QuicheDataWriter writer(data.size(), data.data());
  if (!writer.WriteVarInt62(kKnownLengthRequestFraming)) {
    return absl::InvalidArgumentError("Failed to encode framing indicator.");
  }
  if (const absl::Status status = EncodeControlData(writer); !status.ok()) {
    return status;
  }
  if (const absl::Status status = EncodeKnownLengthFieldsAndBody(writer);
      !status.ok()) {
    return status;
  }
  QUICHE_DCHECK_EQ(writer.remaining(), num_padding_bytes());
  writer.WritePadding();
  return data;
}

absl::StatusOr<BinaryHttpRequest> BinaryHttpRequest::Create(
    absl::string_view data) {
  quiche::QuicheDataReader reader(data);
  uint64_t framing;
  if (!reader.ReadVarInt62(&framing)) {
    return absl::InvalidArgumentError("Missing framing indicator.");
  }
  if (framing == kKnownLengthRequestFraming) {
    return DecodeKnownLengthRequest(reader);
  }
  return absl::UnimplementedError(
      absl::StrCat("Unsupported framing type ", framing));
}

// Returns Ok status only if the decoding processes the Padding section
// successfully or if the message is truncated properly. All other points of
// return are errors.
absl::Status
BinaryHttpRequest::IndeterminateLengthDecoder::DecodeCheckpointData(
    bool end_stream, absl::string_view& checkpoint) {
  QuicheDataReader reader(checkpoint);
  switch (current_section_) {
    case IndeterminateLengthMessageSection::kEnd:
      return absl::InternalError("Decoder is invalid.");
    case IndeterminateLengthMessageSection::kControlData: {
      uint64_t framing;
      if (!reader.ReadVarInt62(&framing)) {
        return absl::OutOfRangeError("Failed to read framing.");
      }
      if (framing != kIndeterminateLengthRequestFraming) {
        return absl::InvalidArgumentError(
            absl::StrFormat("Unsupported framing type: 0x%02x", framing));
      }

      const absl::StatusOr<BinaryHttpRequest::ControlData> control_data =
          DecodeControlData(reader);
      // Only fails if there is not enough data to read the entire control data.
      if (!control_data.ok()) {
        return absl::OutOfRangeError("Failed to read control data.");
      }

      const absl::Status section_status =
          message_section_handler_.OnControlData(control_data.value());
      if (!section_status.ok()) {
        return absl::InternalError(absl::StrCat(
            "Failed to handle control data: ", section_status.message()));
      }
      UpdateChunkedDecodingCheckpoint(reader, checkpoint);
      current_section_ = IndeterminateLengthMessageSection::kHeader;
    }
      ABSL_FALLTHROUGH_INTENDED;
    case IndeterminateLengthMessageSection::kHeader: {
      QUICHE_RETURN_IF_ERROR(DecodeContentTerminatedFieldSection(
          reader, checkpoint,
          absl::bind_front(&MessageSectionHandler::OnHeader,
                           &message_section_handler_)));
      const absl::Status section_status =
          message_section_handler_.OnHeadersDone();
      if (!section_status.ok()) {
        return absl::InternalError(absl::StrCat(
            "Failed to handle headers done: ", section_status.message()));
      }
      current_section_ = IndeterminateLengthMessageSection::kBody;
    }
      ABSL_FALLTHROUGH_INTENDED;
    case IndeterminateLengthMessageSection::kBody: {
      // Body and trailers truncation is valid only if:
      // 1. There is no data to read after the headers section.
      // 2. This is signaled as the last piece of data (end_stream).
      if (reader.IsDoneReading() && end_stream) {
        absl::Status section_status =
            message_section_handler_.OnBodyChunksDone();
        if (!section_status.ok()) {
          return absl::InternalError(absl::StrCat(
              "Failed to handle body chunks done: ", section_status.message()));
        }
        section_status = message_section_handler_.OnTrailersDone();
        if (!section_status.ok()) {
          return absl::InternalError(absl::StrCat(
              "Failed to handle trailers done: ", section_status.message()));
        }
        return absl::OkStatus();
      }

      QUICHE_RETURN_IF_ERROR(DecodeContentTerminatedBodyChunkSection(
          reader, checkpoint,
          absl::bind_front(&MessageSectionHandler::OnBodyChunk,
                           &message_section_handler_)));
      const absl::Status section_status =
          message_section_handler_.OnBodyChunksDone();
      if (!section_status.ok()) {
        return absl::InternalError(absl::StrCat(
            "Failed to handle body chunks done: ", section_status.message()));
      }
      current_section_ = IndeterminateLengthMessageSection::kTrailer;
    }
      ABSL_FALLTHROUGH_INTENDED;
    case IndeterminateLengthMessageSection::kTrailer: {
      // Trailers truncation is valid only if:
      // 1. There is no data to read after the body section.
      // 2. This is signaled as the last piece of data (end_stream).
      if (reader.IsDoneReading() && end_stream) {
        const absl::Status section_status =
            message_section_handler_.OnTrailersDone();
        if (!section_status.ok()) {
          return absl::InternalError(absl::StrCat(
              "Failed to handle trailers done: ", section_status.message()));
        }
        return absl::OkStatus();
      }

      QUICHE_RETURN_IF_ERROR(DecodeContentTerminatedFieldSection(
          reader, checkpoint,
          absl::bind_front(&MessageSectionHandler::OnTrailer,
                           &message_section_handler_)));
      const absl::Status section_status =
          message_section_handler_.OnTrailersDone();
      if (!section_status.ok()) {
        return absl::InternalError(absl::StrCat(
            "Failed to handle trailers done: ", section_status.message()));
      }
      current_section_ = IndeterminateLengthMessageSection::kPadding;
    }
      ABSL_FALLTHROUGH_INTENDED;
    case IndeterminateLengthMessageSection::kPadding: {
      if (!IsValidPadding(reader.PeekRemainingPayload())) {
        return absl::InvalidArgumentError("Non-zero padding.");
      }
      return absl::OkStatus();
    }
  }
  // This should never happen because current_section_ is private and we only
  // ever set it to values handled by the switch statement above.
  return absl::InternalError(
      "Unexpected IndeterminateLengthMessageSection value.");
}

absl::Status BinaryHttpRequest::IndeterminateLengthDecoder::Decode(
    absl::string_view data, bool end_stream) {
  if (current_section_ == IndeterminateLengthMessageSection::kEnd) {
    return absl::InternalError("Decoder is invalid.");
  }

  absl::string_view checkpoint =
      InitializeChunkedDecodingCheckpoint(data, buffer_);
  absl::Status status = DecodeCheckpointData(end_stream, checkpoint);
  if (end_stream) {
    current_section_ = IndeterminateLengthMessageSection::kEnd;
    buffer_.clear();
    // Out of range errors shall be treated as invalid argument errors when the
    // stream is ending.
    if (absl::IsOutOfRange(status)) {
      return absl::InvalidArgumentError(status.message());
    }
    return status;
  }
  if (absl::IsOutOfRange(status)) {
    BufferChunkedDecodingCheckpoint(checkpoint, buffer_);
    return absl::OkStatus();
  }
  if (!status.ok()) {
    current_section_ = IndeterminateLengthMessageSection::kEnd;
  }

  buffer_.clear();
  return status;
}

absl::StatusOr<std::string>
BinaryHttpRequest::IndeterminateLengthEncoder::EncodeFieldSection(
    absl::Span<const FieldView> fields) {
  absl::StatusOr<uint64_t> field_section_length = GetFieldSectionLength(fields);
  if (!field_section_length.ok()) {
    return field_section_length.status();
  }

  std::string data(*field_section_length, '\0');
  QuicheDataWriter writer(*field_section_length, data.data());

  absl::Status fields_encoded = EncodeFields(fields, writer);
  if (!fields_encoded.ok()) {
    return fields_encoded;
  }
  if (writer.remaining() != 0) {
    return absl::InternalError("Failed to write all fields.");
  }
  return data;
}

absl::StatusOr<std::string>
BinaryHttpRequest::IndeterminateLengthEncoder::EncodeControlData(
    const ControlData& control_data) {
  if (current_section_ != IndeterminateLengthMessageSection::kControlData) {
    current_section_ = IndeterminateLengthMessageSection::kEnd;
    return absl::InvalidArgumentError(
        "EncodeControlData called in wrong section.");
  }

  uint64_t total_length = quiche::QuicheDataWriter::GetVarInt62Len(
                              kIndeterminateLengthRequestFraming) +
                          StringPieceVarInt62Len(control_data.method) +
                          StringPieceVarInt62Len(control_data.scheme) +
                          StringPieceVarInt62Len(control_data.authority) +
                          StringPieceVarInt62Len(control_data.path);

  std::string data(total_length, '\0');
  QuicheDataWriter writer(total_length, data.data());
  if (!writer.WriteVarInt62(kIndeterminateLengthRequestFraming)) {
    current_section_ = IndeterminateLengthMessageSection::kEnd;
    return absl::InternalError("Failed to write framing indicator.");
  }
  if (!writer.WriteStringPieceVarInt62(control_data.method)) {
    current_section_ = IndeterminateLengthMessageSection::kEnd;
    return absl::InternalError("Failed to write method.");
  }
  if (!writer.WriteStringPieceVarInt62(control_data.scheme)) {
    current_section_ = IndeterminateLengthMessageSection::kEnd;
    return absl::InternalError("Failed to write scheme.");
  }
  if (!writer.WriteStringPieceVarInt62(control_data.authority)) {
    current_section_ = IndeterminateLengthMessageSection::kEnd;
    return absl::InternalError("Failed to write authority.");
  }
  if (!writer.WriteStringPieceVarInt62(control_data.path)) {
    current_section_ = IndeterminateLengthMessageSection::kEnd;
    return absl::InternalError("Failed to write path.");
  }
  if (writer.remaining() != 0) {
    current_section_ = IndeterminateLengthMessageSection::kEnd;
    return absl::InternalError("Failed to write all control data.");
  }

  current_section_ = IndeterminateLengthMessageSection::kHeader;
  return data;
}

absl::StatusOr<std::string>
BinaryHttpRequest::IndeterminateLengthEncoder::EncodeHeaders(
    absl::Span<const FieldView> headers) {
  if (current_section_ != IndeterminateLengthMessageSection::kHeader) {
    current_section_ = IndeterminateLengthMessageSection::kEnd;
    return absl::InvalidArgumentError("EncodeHeaders called in wrong section.");
  }
  absl::StatusOr<std::string> data = EncodeFieldSection(headers);
  if (!data.ok()) {
    current_section_ = IndeterminateLengthMessageSection::kEnd;
    return data;
  }
  current_section_ = IndeterminateLengthMessageSection::kBody;
  return data;
}

absl::StatusOr<std::string>
BinaryHttpRequest::IndeterminateLengthEncoder::EncodeBodyChunks(
    absl::Span<const absl::string_view> body_chunks, bool body_chunks_done) {
  if (current_section_ != IndeterminateLengthMessageSection::kBody) {
    current_section_ = IndeterminateLengthMessageSection::kEnd;
    return absl::InvalidArgumentError(
        "EncodeBodyChunks called in wrong section.");
  }
  absl::StatusOr<std::string> result =
      EncodeBodyChunksImpl(body_chunks, body_chunks_done);
  if (!result.ok()) {
    current_section_ = IndeterminateLengthMessageSection::kEnd;
    return result.status();
  }
  if (body_chunks_done) {
    current_section_ = IndeterminateLengthMessageSection::kTrailer;
  }
  return result;
}

absl::StatusOr<std::string>
BinaryHttpRequest::IndeterminateLengthEncoder::EncodeTrailers(
    absl::Span<const FieldView> trailers) {
  if (current_section_ != IndeterminateLengthMessageSection::kTrailer) {
    current_section_ = IndeterminateLengthMessageSection::kEnd;
    return absl::InvalidArgumentError(
        "EncodeTrailers called in wrong section.");
  }
  current_section_ = IndeterminateLengthMessageSection::kEnd;
  return EncodeFieldSection(trailers);
}

absl::StatusOr<BinaryHttpResponse> BinaryHttpResponse::Create(
    absl::string_view data) {
  quiche::QuicheDataReader reader(data);
  uint64_t framing;
  if (!reader.ReadVarInt62(&framing)) {
    return absl::InvalidArgumentError("Missing framing indicator.");
  }
  if (framing == kKnownLengthResponseFraming) {
    return DecodeKnownLengthResponse(reader);
  }
  return absl::UnimplementedError(
      absl::StrCat("Unsupported framing type ", framing));
}

absl::StatusOr<std::string>
BinaryHttpResponse::IndeterminateLengthEncoder::EncodeFieldSection(
    std::optional<uint16_t> status_code, absl::Span<const FieldView> fields) {
  absl::StatusOr<uint64_t> field_section_length = GetFieldSectionLength(fields);
  if (!field_section_length.ok()) {
    return field_section_length.status();
  }
  uint64_t total_length = *field_section_length;
  if (current_section_ ==
      IndeterminateLengthMessageSection::kFramingIndicator) {
    total_length += quiche::QuicheDataWriter::GetVarInt62Len(
        kIndeterminateLengthResponseFraming);
  }
  if (status_code.has_value()) {
    total_length += QuicheDataWriter::GetVarInt62Len(*status_code);
  }

  std::string data(total_length, '\0');
  QuicheDataWriter writer(total_length, data.data());

  if (current_section_ ==
      IndeterminateLengthMessageSection::kFramingIndicator) {
    if (!writer.WriteVarInt62(kIndeterminateLengthResponseFraming)) {
      return absl::InternalError("Failed to write framing indicator.");
    }
    current_section_ =
        IndeterminateLengthMessageSection::kInformationalOrFinalStatusCode;
  }
  if (status_code.has_value() && !writer.WriteVarInt62(*status_code)) {
    return absl::InternalError("Failed to write status code.");
  }
  absl::Status fields_encoded = EncodeFields(fields, writer);
  if (!fields_encoded.ok()) {
    return fields_encoded;
  }
  if (writer.remaining() != 0) {
    return absl::InternalError("Failed to write all data.");
  }
  return data;
}

std::string
BinaryHttpResponse::IndeterminateLengthEncoder::GetMessageSectionString(
    IndeterminateLengthMessageSection section) const {
  switch (section) {
    case IndeterminateLengthMessageSection::kFramingIndicator:
      return "FramingIndicator";
    case IndeterminateLengthMessageSection::kInformationalOrFinalStatusCode:
      return "InformationalOrFinalStatusCode";
    case IndeterminateLengthMessageSection::kInformationalResponseHeader:
      return "InformationalResponseHeader";
    case IndeterminateLengthMessageSection::kFinalResponseHeader:
      return "FinalResponseHeader";
    case IndeterminateLengthMessageSection::kBody:
      return "Body";
    case IndeterminateLengthMessageSection::kTrailer:
      return "Trailer";
    case IndeterminateLengthMessageSection::kPadding:
      return "Padding";
    case IndeterminateLengthMessageSection::kEnd:
      return "End";
    default:
      return "Unknown";
  }
}

absl::StatusOr<std::string>
BinaryHttpResponse::IndeterminateLengthEncoder::EncodeInformationalResponse(
    uint16_t status_code, absl::Span<const FieldView> fields) {
  if (current_section_ !=
          IndeterminateLengthMessageSection::kFramingIndicator &&
      current_section_ !=
          IndeterminateLengthMessageSection::kInformationalOrFinalStatusCode) {
    current_section_ = IndeterminateLengthMessageSection::kEnd;
    return absl::InvalidArgumentError(absl::StrCat(
        "EncodeInformationalResponse called in incorrect section: ",
        GetMessageSectionString(current_section_)));
  }
  if (status_code < kMinInformationalStatusCode ||
      status_code > kMaxInformationalStatusCode) {
    current_section_ = IndeterminateLengthMessageSection::kEnd;
    return absl::InvalidArgumentError(absl::StrCat(
        "Invalid informational response status code: ", status_code));
  }

  absl::StatusOr<std::string> data = EncodeFieldSection(status_code, fields);
  if (!data.ok()) {
    current_section_ = IndeterminateLengthMessageSection::kEnd;
  }
  current_section_ =
      IndeterminateLengthMessageSection::kInformationalOrFinalStatusCode;
  return data;
}

absl::StatusOr<std::string>
BinaryHttpResponse::IndeterminateLengthEncoder::EncodeHeaders(
    uint16_t status_code, absl::Span<const FieldView> headers) {
  if (current_section_ !=
          IndeterminateLengthMessageSection::kFramingIndicator &&
      current_section_ !=
          IndeterminateLengthMessageSection::kInformationalOrFinalStatusCode) {
    current_section_ = IndeterminateLengthMessageSection::kEnd;
    return absl::InvalidArgumentError(
        absl::StrCat("EncodeHeaders called in incorrect section: ",
                     GetMessageSectionString(current_section_)));
  }
  if (status_code < kMinFinalStatusCode || status_code > kMaxFinalStatusCode) {
    current_section_ = IndeterminateLengthMessageSection::kEnd;
    return absl::InvalidArgumentError(
        absl::StrCat("Invalid response status code: ", status_code));
  }

  absl::StatusOr<std::string> data = EncodeFieldSection(status_code, headers);
  if (!data.ok()) {
    current_section_ = IndeterminateLengthMessageSection::kEnd;
    return data;
  }
  current_section_ = IndeterminateLengthMessageSection::kBody;
  return data;
}

absl::StatusOr<std::string>
BinaryHttpResponse::IndeterminateLengthEncoder::EncodeBodyChunks(
    absl::Span<const absl::string_view> body_chunks, bool body_chunks_done) {
  if (current_section_ != IndeterminateLengthMessageSection::kBody) {
    current_section_ = IndeterminateLengthMessageSection::kEnd;
    return absl::InvalidArgumentError(
        absl::StrCat("EncodeBodyChunks called in incorrect section: ",
                     GetMessageSectionString(current_section_)));
  }
  absl::StatusOr<std::string> result =
      EncodeBodyChunksImpl(body_chunks, body_chunks_done);
  if (!result.ok()) {
    current_section_ = IndeterminateLengthMessageSection::kEnd;
    return result.status();
  }
  if (body_chunks_done) {
    current_section_ = IndeterminateLengthMessageSection::kTrailer;
  }
  return result;
}

absl::StatusOr<std::string>
BinaryHttpResponse::IndeterminateLengthEncoder::EncodeTrailers(
    absl::Span<const FieldView> trailers) {
  if (current_section_ != IndeterminateLengthMessageSection::kTrailer) {
    current_section_ = IndeterminateLengthMessageSection::kEnd;
    return absl::InvalidArgumentError(
        absl::StrCat("EncodeTrailers called in incorrect section: ",
                     GetMessageSectionString(current_section_)));
  }

  absl::StatusOr<std::string> data =
      EncodeFieldSection(/*status_code=*/std::nullopt, trailers);

  current_section_ = IndeterminateLengthMessageSection::kEnd;
  return data;
}

std::string BinaryHttpMessage::DebugString() const {
  std::vector<std::string> headers;
  for (const auto& field : GetHeaderFields()) {
    headers.emplace_back(field.DebugString());
  }
  return absl::StrCat("BinaryHttpMessage{Headers{", absl::StrJoin(headers, ";"),
                      "}Body{", body(), "}}");
}

std::string BinaryHttpMessage::Field::DebugString() const {
  return absl::StrCat("Field{", name, "=", value, "}");
}

std::string BinaryHttpResponse::InformationalResponse::DebugString() const {
  std::vector<std::string> fs;
  for (const auto& field : fields()) {
    fs.emplace_back(field.DebugString());
  }
  return absl::StrCat("InformationalResponse{", absl::StrJoin(fs, ";"), "}");
}

std::string BinaryHttpResponse::DebugString() const {
  std::vector<std::string> irs;
  for (const auto& ir : informational_responses()) {
    irs.emplace_back(ir.DebugString());
  }
  return absl::StrCat("BinaryHttpResponse(", status_code_, "){",
                      BinaryHttpMessage::DebugString(), absl::StrJoin(irs, ";"),
                      "}");
}

std::string BinaryHttpRequest::DebugString() const {
  return absl::StrCat("BinaryHttpRequest{", BinaryHttpMessage::DebugString(),
                      "}");
}

absl::Status BinaryHttpResponse::IndeterminateLengthDecoder::DecodeStatusCode(
    QuicheDataReader& reader, absl::string_view& checkpoint) {
  uint64_t status_code = 0;
  if (!reader.ReadVarInt62(&status_code)) {
    return absl::OutOfRangeError("Failed to read status code.");
  } else if (status_code < kMinInformationalStatusCode ||
             status_code > kMaxFinalStatusCode) {
    return absl::InvalidArgumentError(
        absl::StrCat("Invalid response status code: ", status_code));
  } else if (status_code >= kMinInformationalStatusCode &&
             status_code <= kMaxInformationalStatusCode) {
    if (absl::Status status =
            message_section_handler_.OnInformationalResponseStatusCode(
                status_code);
        !status.ok()) {
      return absl::InternalError(
          absl::StrCat("Failed to handle informational response status "
                       "code: ",
                       status.message()));
    }
    current_section_ =
        IndeterminateLengthMessageSection::kInformationalResponseHeader;
  } else {
    if (absl::Status status =
            message_section_handler_.OnInformationalResponsesSectionDone();
        !status.ok()) {
      return absl::InternalError(absl::StrCat(
          "Failed to handle informational responses section done: ",
          status.message()));
    } else if (status = message_section_handler_.OnFinalResponseStatusCode(
                   status_code);
               !status.ok()) {
      return absl::InternalError(absl::StrCat(
          "Failed to handle final response status code: ", status.message()));
    }
    current_section_ = IndeterminateLengthMessageSection::kFinalResponseHeader;
  }
  UpdateChunkedDecodingCheckpoint(reader, checkpoint);
  return absl::OkStatus();
}

// Returns Ok status only if the decoding processes the Padding section
// successfully or if the message is truncated properly. All other points of
// return are errors.
absl::Status
BinaryHttpResponse::IndeterminateLengthDecoder::DecodeCheckpointData(
    bool end_stream, absl::string_view& checkpoint) {
  QuicheDataReader reader(checkpoint);
  // We only enter the loop if there is data in the reader or if end_stream is
  // true. The check for end_stream is used when the reader is done to validate
  // if it is a truncated message.
  while (!reader.IsDoneReading() || end_stream) {
    switch (current_section_) {
      case IndeterminateLengthMessageSection::kEnd:
        return absl::InternalError("Decoder is invalid.");
      case IndeterminateLengthMessageSection::kFramingIndicator: {
        uint64_t framing = 0;
        if (!reader.ReadVarInt62(&framing)) {
          return absl::OutOfRangeError("Failed to read framing.");
        } else if (framing != kIndeterminateLengthResponseFraming) {
          return absl::InvalidArgumentError(
              absl::StrFormat("Unsupported framing type: 0x%02x", framing));
        }
        current_section_ =
            IndeterminateLengthMessageSection::kInformationalOrFinalStatusCode;
        UpdateChunkedDecodingCheckpoint(reader, checkpoint);
        break;
      }
      case IndeterminateLengthMessageSection::kInformationalOrFinalStatusCode: {
        QUICHE_RETURN_IF_ERROR(DecodeStatusCode(reader, checkpoint));
        break;
      }
      case IndeterminateLengthMessageSection::kInformationalResponseHeader: {
        QUICHE_RETURN_IF_ERROR(DecodeContentTerminatedFieldSection(
            reader, checkpoint,
            absl::bind_front(
                &MessageSectionHandler::OnInformationalResponseHeader,
                &message_section_handler_)));
        if (absl::Status status =
                message_section_handler_.OnInformationalResponseDone();
            !status.ok()) {
          return absl::InternalError(
              absl::StrCat("Failed to handle informational response done: ",
                           status.message()));
        }
        current_section_ =
            IndeterminateLengthMessageSection::kInformationalOrFinalStatusCode;
        break;
      }
      case IndeterminateLengthMessageSection::kFinalResponseHeader: {
        QUICHE_RETURN_IF_ERROR(DecodeContentTerminatedFieldSection(
            reader, checkpoint,
            absl::bind_front(&MessageSectionHandler::OnFinalResponseHeader,
                             &message_section_handler_)));
        if (absl::Status status =
                message_section_handler_.OnFinalResponseHeadersDone();
            !status.ok()) {
          return absl::InternalError(absl::StrCat(
              "Failed to handle headers done: ", status.message()));
        }
        current_section_ = IndeterminateLengthMessageSection::kBody;
        UpdateChunkedDecodingCheckpoint(reader, checkpoint);
        break;
      }
      case IndeterminateLengthMessageSection::kBody: {
        // Body and trailers truncation is valid only if:
        // 1. There is no data to read after the headers section.
        // 2. This is signaled as the last piece of data (end_stream).
        if (reader.IsDoneReading() && end_stream) {
          if (absl::Status status = message_section_handler_.OnBodyChunksDone();
              !status.ok()) {
            return absl::InternalError(absl::StrCat(
                "Failed to handle body chunks done: ", status.message()));
          } else if (status = message_section_handler_.OnTrailersDone();
                     !status.ok()) {
            return absl::InternalError(absl::StrCat(
                "Failed to handle trailers done: ", status.message()));
          }
          return absl::OkStatus();
        }

        QUICHE_RETURN_IF_ERROR(DecodeContentTerminatedBodyChunkSection(
            reader, checkpoint,
            absl::bind_front(&MessageSectionHandler::OnBodyChunk,
                             &message_section_handler_)));
        if (absl::Status status = message_section_handler_.OnBodyChunksDone();
            !status.ok()) {
          return absl::InternalError(absl::StrCat(
              "Failed to handle body chunks done: ", status.message()));
        }
        current_section_ = IndeterminateLengthMessageSection::kTrailer;
        break;
      }
      case IndeterminateLengthMessageSection::kTrailer: {
        // Trailers truncation is valid only if:
        // 1. There is no data to read after the body section.
        // 2. This is signaled as the last piece of data (end_stream).
        if (reader.IsDoneReading() && end_stream) {
          if (absl::Status status = message_section_handler_.OnTrailersDone();
              !status.ok()) {
            return absl::InternalError(absl::StrCat(
                "Failed to handle trailers done: ", status.message()));
          }
          return absl::OkStatus();
        }

        QUICHE_RETURN_IF_ERROR(DecodeContentTerminatedFieldSection(
            reader, checkpoint,
            absl::bind_front(&MessageSectionHandler::OnTrailer,
                             &message_section_handler_)));
        if (absl::Status status = message_section_handler_.OnTrailersDone();
            !status.ok()) {
          return absl::InternalError(absl::StrCat(
              "Failed to handle trailers done: ", status.message()));
        }
        current_section_ = IndeterminateLengthMessageSection::kPadding;
        break;
      }
      case IndeterminateLengthMessageSection::kPadding: {
        if (!IsValidPadding(reader.PeekRemainingPayload())) {
          return absl::InvalidArgumentError("Non-zero padding.");
        }
        return absl::OkStatus();
      }
    }
  }
  // No data in the reader and no end_stream, signal that more data is pending
  // using OutOfRange.
  return absl::OutOfRangeError("Decoding is pending.");
}

absl::Status BinaryHttpResponse::IndeterminateLengthDecoder::Decode(
    absl::string_view data, bool end_stream) {
  if (current_section_ == IndeterminateLengthMessageSection::kEnd) {
    return absl::InternalError("Decoder is invalid.");
  }

  absl::string_view checkpoint =
      InitializeChunkedDecodingCheckpoint(data, buffer_);
  absl::Status status = DecodeCheckpointData(end_stream, checkpoint);
  if (end_stream) {
    current_section_ = IndeterminateLengthMessageSection::kEnd;
    buffer_.clear();
    // Out of range errors shall be treated as invalid argument errors when the
    // stream is ending.
    if (absl::IsOutOfRange(status)) {
      return absl::InvalidArgumentError(status.message());
    }
    return status;
  } else if (absl::IsOutOfRange(status)) {
    BufferChunkedDecodingCheckpoint(checkpoint, buffer_);
    return absl::OkStatus();
  } else if (!status.ok()) {
    current_section_ = IndeterminateLengthMessageSection::kEnd;
  }

  buffer_.clear();
  return status;
}

void PrintTo(const BinaryHttpRequest& msg, std::ostream* os) {
  *os << msg.DebugString();
}

void PrintTo(const BinaryHttpResponse& msg, std::ostream* os) {
  *os << msg.DebugString();
}

void PrintTo(const BinaryHttpMessage::Field& msg, std::ostream* os) {
  *os << msg.DebugString();
}

}  // namespace quiche
