#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/base/attributes.h"
#include "absl/base/nullability.h"
#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;
  };

  // Creates a new IndeterminateLengthDecoder. Does not take ownership of
  // `message_section_handler`, which must refer to a valid handler that
  // outlives this decoder.
  static absl::StatusOr<BinaryHttpRequest::IndeterminateLengthDecoder> Create(
      MessageSectionHandler* absl_nonnull message_section_handler
          ABSL_ATTRIBUTE_LIFETIME_BOUND) {
    if (message_section_handler == nullptr) {
      return absl::InvalidArgumentError("MessageSectionHandler is null");
    }
    return BinaryHttpRequest::IndeterminateLengthDecoder(
        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:
  explicit IndeterminateLengthDecoder(
      MessageSectionHandler* absl_nonnull message_section_handler
          ABSL_ATTRIBUTE_LIFETIME_BOUND)
      : message_section_handler_(*message_section_handler) {}
  // 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,
                                    absl::string_view& checkpoint);

  // The handler to invoke when a section is decoded successfully. The
  // handler can return an error if the decoded data cannot be processed
  // successfully. Not owned.
  MessageSectionHandler& message_section_handler_;
  // Stores the data that could not be processed due to missing data.
  std::string buffer_;
  // The current section that is being decoded.
  IndeterminateLengthMessageSection current_section_ =
      IndeterminateLengthMessageSection::kControlData;
};

// 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 {
    kFramingIndicator,
    kInformationalOrFinalStatusCode,
    kInformationalResponseHeader,
    kFinalResponseHeader,
    kBody,
    kTrailer,
    kPadding,
    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::kFramingIndicator;
};

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

#endif  // QUICHE_BINARY_HTTP_BINARY_HTTP_MESSAGE_H_
