#ifndef QUICHE_BINARY_HTTP_BINARY_HTTP_MESSAGE_H_
#define QUICHE_BINARY_HTTP_BINARY_HTTP_MESSAGE_H_

#include <cstddef>
#include <cstdint>
#include <functional>
#include <memory>
#include <optional>
#include <ostream>
#include <string>
#include <utility>
#include <vector>

#include "absl/container/flat_hash_map.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include "absl/types/span.h"
#include "quiche/common/platform/api/quiche_export.h"
#include "quiche/common/quiche_data_reader.h"
#include "quiche/common/quiche_data_writer.h"

namespace quiche {

// Supports encoding and decoding Binary Http messages.
// Currently limited to known-length messages.
// https://www.ietf.org/archive/id/draft-ietf-httpbis-binary-message-06.html
class QUICHE_EXPORT BinaryHttpMessage {
 public:
  // A view of a field name and value. Used to pass around a field without
  // owning or copying the backing data.
  struct QUICHE_EXPORT FieldView {
    absl::string_view name;
    absl::string_view value;
  };
  // Name value pair of either a header or trailer field.
  struct QUICHE_EXPORT Field {
    std::string name;
    std::string value;
    bool operator==(const BinaryHttpMessage::Field& rhs) const {
      return name == rhs.name && value == rhs.value;
    }

    bool operator!=(const BinaryHttpMessage::Field& rhs) const {
      return !(*this == rhs);
    }

    std::string DebugString() const;
  };
  virtual ~BinaryHttpMessage() = default;

  // TODO(bschneider): Switch to use existing Http2HeaderBlock
  BinaryHttpMessage* AddHeaderField(Field header_field);

  const std::vector<Field>& GetHeaderFields() const {
    return header_fields_.fields();
  }

  BinaryHttpMessage* set_body(std::string body) {
    body_ = std::move(body);
    return this;
  }

  void swap_body(std::string& body) { body_.swap(body); }
  void set_num_padding_bytes(size_t num_padding_bytes) {
    num_padding_bytes_ = num_padding_bytes;
  }
  size_t num_padding_bytes() const { return num_padding_bytes_; }

  absl::string_view body() const { return body_; }

  // Returns the number of bytes `Serialize` will return, including padding.
  virtual size_t EncodedSize() const = 0;

  // Returns the Binary Http formatted message.
  virtual absl::StatusOr<std::string> Serialize() const = 0;
  // TODO(bschneider): Add AddTrailerField for chunked messages
  // TODO(bschneider): Add SetBodyCallback() for chunked messages

  virtual std::string DebugString() const;

 protected:
  class Fields {
   public:
    // Appends `field` to list of fields.  Can contain duplicates.
    void AddField(BinaryHttpMessage::Field field);

    const std::vector<BinaryHttpMessage::Field>& fields() const {
      return fields_;
    }

    bool operator==(const BinaryHttpMessage::Fields& rhs) const {
      return fields_ == rhs.fields_;
    }

    // Encode fields in insertion order.
    // https://www.ietf.org/archive/id/draft-ietf-httpbis-binary-message-06.html#name-header-and-trailer-field-li
    absl::Status Encode(quiche::QuicheDataWriter& writer) const;

    // The number of returned by EncodedFieldsSize
    // plus the number of bytes used in the varint holding that value.
    size_t EncodedSize() const;

   private:
    // Number of bytes of just the set of fields.
    size_t EncodedFieldsSize() const;

    // Fields in insertion order.
    std::vector<BinaryHttpMessage::Field> fields_;
  };

  // Checks equality excluding padding.
  bool IsPayloadEqual(const BinaryHttpMessage& rhs) const {
    // `has_host_` is derived from `header_fields_` so it doesn't need to be
    // tested directly.
    return body_ == rhs.body_ && header_fields_ == rhs.header_fields_;
  }

  absl::Status EncodeKnownLengthFieldsAndBody(
      quiche::QuicheDataWriter& writer) const;
  size_t EncodedKnownLengthFieldsAndBodySize() const;
  bool has_host() const { return has_host_; }

 private:
  std::string body_;
  Fields header_fields_;
  bool has_host_ = false;
  size_t num_padding_bytes_ = 0;
};

void QUICHE_EXPORT PrintTo(const BinaryHttpMessage::Field& msg,
                           std::ostream* os);

class QUICHE_EXPORT BinaryHttpRequest : public BinaryHttpMessage {
 public:
  // HTTP request must have method, scheme, and path fields.
  // The `authority` field is required unless a `host` header field is added.
  // If a `host` header field is added, `authority` is serialized as the empty
  // string.
  // Some examples are:
  //   scheme: HTTP
  //   authority: www.example.com
  //   path: /index.html
  struct QUICHE_EXPORT ControlData {
    std::string method;
    std::string scheme;
    std::string authority;
    std::string path;
    bool operator==(const BinaryHttpRequest::ControlData& rhs) const {
      return method == rhs.method && scheme == rhs.scheme &&
             authority == rhs.authority && path == rhs.path;
    }
    bool operator!=(const BinaryHttpRequest::ControlData& rhs) const {
      return !(*this == rhs);
    }
  };
  explicit BinaryHttpRequest(ControlData control_data)
      : control_data_(std::move(control_data)) {}

  // Deserialize
  static absl::StatusOr<BinaryHttpRequest> Create(absl::string_view data);

  size_t EncodedSize() const override;
  absl::StatusOr<std::string> Serialize() const override;
  const ControlData& control_data() const { return control_data_; }

  virtual std::string DebugString() const override;

  // Returns true if the contents of the requests are equal, excluding padding.
  bool IsPayloadEqual(const BinaryHttpRequest& rhs) const {
    return control_data_ == rhs.control_data_ &&
           BinaryHttpMessage::IsPayloadEqual(rhs);
  }

  bool operator==(const BinaryHttpRequest& rhs) const {
    return IsPayloadEqual(rhs) &&
           num_padding_bytes() == rhs.num_padding_bytes();
  }

  bool operator!=(const BinaryHttpRequest& rhs) const {
    return !(*this == rhs);
  }

  // Provides a Decode method that can be called multiple times as data is
  // received. The relevant MessageSectionHandler method will be called when
  // its corresponding section is successfully decoded.
  class QUICHE_EXPORT IndeterminateLengthDecoder;

  // Provides encoding methods for an Indeterminate-Length BHTTP request. The
  // encoder keeps track of what has been encoded so far to ensure sections are
  // encoded in the correct order, this means it can only be used for a single
  // request message.
  class QUICHE_EXPORT IndeterminateLengthEncoder;

 private:
  // The sections of an Indeterminate-Length BHTTP request.
  enum class IndeterminateLengthMessageSection {
    kControlData,
    kHeader,
    kBody,
    kTrailer,
    kPadding,
    // The decoder/encoder is set to end after the message is marked as complete
    // or if an error occurs while processing the message.
    kEnd,
  };
  absl::Status EncodeControlData(quiche::QuicheDataWriter& writer) const;

  size_t EncodedControlDataSize() const;

  // Returns Binary Http known length request formatted request.
  absl::StatusOr<std::string> EncodeAsKnownLength() const;

  const ControlData control_data_;
};

// Provides a Decode method that can be called multiple times as data is
// received. The relevant MessageSectionHandler method will be called when
// its corresponding section is successfully decoded.
class QUICHE_EXPORT BinaryHttpRequest::IndeterminateLengthDecoder {
 public:
  // The handler to invoke when a section is decoded successfully. The
  // handler can return an error if the decoded data cannot be processed
  // successfully.
  class QUICHE_EXPORT MessageSectionHandler {
   public:
    virtual ~MessageSectionHandler() = default;
    virtual absl::Status OnControlData(const ControlData& control_data) = 0;
    virtual absl::Status OnHeader(absl::string_view name,
                                  absl::string_view value) = 0;
    virtual absl::Status OnHeadersDone() = 0;
    virtual absl::Status OnBodyChunk(absl::string_view body_chunk) = 0;
    virtual absl::Status OnBodyChunksDone() = 0;
    virtual absl::Status OnTrailer(absl::string_view name,
                                   absl::string_view value) = 0;
    virtual absl::Status OnTrailersDone() = 0;
  };

  explicit IndeterminateLengthDecoder(
      MessageSectionHandler& message_section_handler)
      : message_section_handler_(message_section_handler) {}

  // Decodes an Indeterminate-Length BHTTP request. As the caller receives
  // portions of the request, the caller can call this method with the request
  // portion. The class keeps track of the current message section that is
  // being decoded and buffers data if the section is not fully decoded so
  // that the next call can continue decoding from where it left off. It will
  // also invoke the appropriate MessageSectionHandler method when a section
  // is decoded successfully.
  // `end_stream` indicates that no more data will be provided to the decoder.
  // This is used to determine if a valid message was decoded properly given
  // the last piece of data provided, handling both complete messages and
  // truncated messages.
  absl::Status Decode(absl::string_view data, bool end_stream);

 private:
  // Initializes the checkpoint with the provided data and any buffered data.
  void InitializeCheckpoint(absl::string_view data);
  // Carries out the decode logic from the checkpoint. Returns
  // OutOfRangeError if there is not enough data to decode the current
  // section. When a section is fully decoded, the checkpoint is updated.
  absl::Status DecodeCheckpointData(bool end_stream);
  // Saves the checkpoint based on the current position of the reader.
  void SaveCheckpoint(const QuicheDataReader& reader) {
    checkpoint_view_ = reader.PeekRemainingPayload();
  }
  // Buffers the checkpoint.
  void BufferCheckpoint() { buffer_ = std::string(checkpoint_view_); }
  // Decodes a section 0 or more times until a content terminator is
  // encountered.
  absl::Status DecodeContentTerminatedSection(QuicheDataReader& reader);

  MessageSectionHandler& message_section_handler_;
  // Stores the data that could not be processed due to missing data.
  std::string buffer_;
  // Tracks the remaining data to be processed or buffered.
  // When decoding fails due to missing data, we buffer based on this
  // checkpoint and return. When decoding succeeds, we update the checkpoint
  // to not buffer the already processed data.
  absl::string_view checkpoint_view_;
  // The current section that is being decoded.
  IndeterminateLengthMessageSection current_section_ =
      IndeterminateLengthMessageSection::kControlData;
  // Upon initial entry of the body or trailer section, the message is assumed
  // to be truncated. This will be set to `false` upon the detection of data,
  // and the state remains consistent for the remainder of the section. This
  // serves to differentiate between true truncation and an `end_stream`
  // occurring after partial processing of the section's content but before
  // its content terminator.
  bool maybe_truncated_ = true;
};

// Provides encoding methods for an Indeterminate-Length BHTTP request. The
// encoder keeps track of what has been encoded so far to ensure sections are
// encoded in the correct order, this means it can only be used for a single
// request message.
class QUICHE_EXPORT BinaryHttpRequest::IndeterminateLengthEncoder {
 public:
  // Encodes the initial framing indicator and the specified control data.
  absl::StatusOr<std::string> EncodeControlData(
      const ControlData& control_data);
  // Encodes the specified headers and its content terminator.
  absl::StatusOr<std::string> EncodeHeaders(absl::Span<FieldView> headers);
  // Encodes the specified body chunks. This can be called multiple times but
  // it needs to be called exactly once with `body_chunks_done` set to true at
  // the end to properly set the content terminator. Encoding body chunks is
  // optional since valid chunked messages can be truncated.
  absl::StatusOr<std::string> EncodeBodyChunks(
      absl::Span<absl::string_view> body_chunks, bool body_chunks_done);
  // Encodes the specified trailers and its content terminator. Encoding
  // trailers is optional since valid chunked messages can be truncated.
  absl::StatusOr<std::string> EncodeTrailers(absl::Span<FieldView> trailers);

 private:
  absl::StatusOr<std::string> EncodeFieldSection(absl::Span<FieldView> fields);

  IndeterminateLengthMessageSection current_section_ =
      IndeterminateLengthMessageSection::kControlData;
};

void QUICHE_EXPORT PrintTo(const BinaryHttpRequest& msg, std::ostream* os);

class QUICHE_EXPORT BinaryHttpResponse : public BinaryHttpMessage {
 public:
  // https://www.ietf.org/archive/id/draft-ietf-httpbis-binary-message-06.html#name-response-control-data
  // A response can contain 0 to N informational responses.  Each informational
  // response contains a status code followed by a header field. Valid status
  // codes are [100,199].
  class QUICHE_EXPORT InformationalResponse {
   public:
    explicit InformationalResponse(uint16_t status_code)
        : status_code_(status_code) {}
    InformationalResponse(uint16_t status_code,
                          const std::vector<BinaryHttpMessage::Field>& fields)
        : status_code_(status_code) {
      for (const BinaryHttpMessage::Field& field : fields) {
        AddField(field.name, field.value);
      }
    }

    bool operator==(
        const BinaryHttpResponse::InformationalResponse& rhs) const {
      return status_code_ == rhs.status_code_ && fields_ == rhs.fields_;
    }

    bool operator!=(
        const BinaryHttpResponse::InformationalResponse& rhs) const {
      return !(*this == rhs);
    }

    // Adds a field with the provided name, converted to lower case.
    // Fields are in the order they are added.
    void AddField(absl::string_view name, std::string value);

    const std::vector<BinaryHttpMessage::Field>& fields() const {
      return fields_.fields();
    }

    uint16_t status_code() const { return status_code_; }

    std::string DebugString() const;

   private:
    // Give BinaryHttpResponse access to Encoding functionality.
    friend class BinaryHttpResponse;

    size_t EncodedSize() const;

    // Appends the encoded fields and body to `writer`.
    absl::Status Encode(quiche::QuicheDataWriter& writer) const;

    const uint16_t status_code_;
    BinaryHttpMessage::Fields fields_;
  };

  explicit BinaryHttpResponse(uint16_t status_code)
      : status_code_(status_code) {}

  // Deserialize
  static absl::StatusOr<BinaryHttpResponse> Create(absl::string_view data);

  size_t EncodedSize() const override;
  absl::StatusOr<std::string> Serialize() const override;

  // Informational status codes must be between 100 and 199 inclusive.
  absl::Status AddInformationalResponse(uint16_t status_code,
                                        std::vector<Field> header_fields);

  uint16_t status_code() const { return status_code_; }

  // References in the returned `ResponseControlData` are invalidated on
  // `BinaryHttpResponse` object mutations.
  const std::vector<InformationalResponse>& informational_responses() const {
    return informational_response_control_data_;
  }

  virtual std::string DebugString() const override;

  // Returns true if the contents of the requests are equal, excluding padding.
  bool IsPayloadEqual(const BinaryHttpResponse& rhs) const {
    return informational_response_control_data_ ==
               rhs.informational_response_control_data_ &&
           status_code_ == rhs.status_code_ &&
           BinaryHttpMessage::IsPayloadEqual(rhs);
  }

  bool operator==(const BinaryHttpResponse& rhs) const {
    return IsPayloadEqual(rhs) &&
           num_padding_bytes() == rhs.num_padding_bytes();
  }

  bool operator!=(const BinaryHttpResponse& rhs) const {
    return !(*this == rhs);
  }

  // Provides encoding methods for an Indeterminate-Length BHTTP response. The
  // encoder keeps track of what has been encoded so far to ensure sections are
  // encoded in the correct order, this means it can only be used for a single
  // BHTTP response message.
  class QUICHE_EXPORT IndeterminateLengthEncoder;

 private:
  enum class IndeterminateLengthMessageSection {
    kInformationalResponseOrHeader,
    kBody,
    kTrailer,
    kEnd,
  };
  // Returns Binary Http known length request formatted response.
  absl::StatusOr<std::string> EncodeAsKnownLength() const;

  std::vector<InformationalResponse> informational_response_control_data_;
  const uint16_t status_code_;
};

// Provides encoding methods for an Indeterminate-Length BHTTP response. The
// encoder keeps track of what has been encoded so far to ensure sections are
// encoded in the correct order, this means it can only be used for a single
// BHTTP response message.
class QUICHE_EXPORT BinaryHttpResponse::IndeterminateLengthEncoder {
 public:
  // Encodes the specified informational response status code, fields, and its
  // content terminator.
  absl::StatusOr<std::string> EncodeInformationalResponse(
      uint16_t status_code, absl::Span<FieldView> fields);
  // Encodes the specified status code, headers, and its content terminator.
  absl::StatusOr<std::string> EncodeHeaders(uint16_t status_code,
                                            absl::Span<FieldView> headers);
  // Encodes the specified body chunks. This can be called multiple times but
  // it needs to be called exactly once with `body_chunks_done` set to true at
  // the end to properly set the content terminator. Encoding body chunks is
  // optional since valid chunked messages can be truncated.
  absl::StatusOr<std::string> EncodeBodyChunks(
      absl::Span<absl::string_view> body_chunks, bool body_chunks_done);
  // Encodes the specified trailers and its content terminator. Encoding
  // trailers is optional since valid chunked messages can be truncated.
  absl::StatusOr<std::string> EncodeTrailers(absl::Span<FieldView> trailers);

 private:
  absl::StatusOr<std::string> EncodeFieldSection(
      std::optional<uint16_t> status_code, absl::Span<FieldView> fields);
  std::string GetMessageSectionString(
      IndeterminateLengthMessageSection section) const;

  IndeterminateLengthMessageSection current_section_ =
      IndeterminateLengthMessageSection::kInformationalResponseOrHeader;
  bool framing_indicator_encoded_ = false;
};

void QUICHE_EXPORT PrintTo(const BinaryHttpResponse& msg, std::ostream* os);
}  // namespace quiche

#endif  // QUICHE_BINARY_HTTP_BINARY_HTTP_MESSAGE_H_
