#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 {
   public:
    // The handler to invoke when a section is decoded successfully.
    class QUICHE_EXPORT MessageSectionHandler {
     public:
      virtual ~MessageSectionHandler() = default;
      virtual void OnControlData(const ControlData& control_data) = 0;
      virtual void OnHeader(absl::string_view name,
                            absl::string_view value) = 0;
      virtual void OnHeadersDone() = 0;
      virtual void OnBodyChunk(absl::string_view body_chunk) = 0;
      virtual void OnBodyChunksDone() = 0;
      virtual void OnTrailer(absl::string_view name,
                             absl::string_view value) = 0;
      virtual void 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:
    // The sections of an Indeterminate-Length BHTTP request.
    enum class MessageSection {
      kControlData,
      kHeader,
      kBody,
      kTrailer,
      kPadding,
      // The decoder is set to end after end_stream is received or when an error
      // occurs while decoding.
      kEnd,
    };

    // 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.
    MessageSection current_section_ = MessageSection::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;
  };

 private:
  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_;
};

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 {
   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. If 'body_chunks_done' is true, the
    // encoded body chunks are followed by the content terminator.
    absl::StatusOr<std::string> EncodeBodyChunks(
        absl::Span<absl::string_view> body_chunks, bool body_chunks_done);
    // Encodes the specified trailers and its content terminator.
    absl::StatusOr<std::string> EncodeTrailers(absl::Span<FieldView> trailers);

   private:
    enum class MessageSection {
      kInformationalResponseOrHeader,
      kBody,
      kTrailer,
      kEnd,
    };
    absl::StatusOr<std::string> EncodeFieldSection(
        std::optional<uint16_t> status_code, absl::Span<FieldView> fields);
    std::string GetMessageSectionString(MessageSection section) const;

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

 private:
  // 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_;
};

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

#endif  // QUICHE_BINARY_HTTP_BINARY_HTTP_MESSAGE_H_
