// Copyright (c) 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef QUICHE_QUIC_CORE_QPACK_QPACK_INSTRUCTIONS_H_
#define QUICHE_QUIC_CORE_QPACK_QPACK_INSTRUCTIONS_H_

#include <cstdint>
#include <string>
#include <tuple>
#include <vector>

#include "absl/strings/string_view.h"
#include "quic/platform/api/quic_export.h"

namespace quic {

namespace test {
class QpackInstructionWithValuesPeer;
}  // namespace test

// Each instruction is identified with an opcode in the first byte.
// |mask| determines which bits are part of the opcode.
// |value| is the value of these bits.  (Other bits in value must be zero.)
struct QUIC_EXPORT_PRIVATE QpackInstructionOpcode {
  uint8_t value;
  uint8_t mask;
};

bool operator==(const QpackInstructionOpcode& a,
                const QpackInstructionOpcode& b);

// Possible types of an instruction field.  Decoding a static bit does not
// consume the current byte.  Decoding an integer or a length-prefixed string
// literal consumes all bytes containing the field value.
enum class QpackInstructionFieldType {
  // A single bit indicating whether the index refers to the static table, or
  // indicating the sign of Delta Base.  Called "S" bit because both "static"
  // and "sign" start with the letter "S".
  kSbit,
  // An integer encoded with variable length encoding.  This could be an index,
  // stream ID, maximum size, or Encoded Required Insert Count.
  kVarint,
  // A second integer encoded with variable length encoding.  This could be
  // Delta Base.
  kVarint2,
  // A header name or header value encoded as:
  //   a bit indicating whether it is Huffman encoded;
  //   the encoded length of the string;
  //   the header name or value optionally Huffman encoded.
  kName,
  kValue
};

// Each instruction field has a type and a parameter.
// The meaning of the parameter depends on the field type.
struct QUIC_EXPORT_PRIVATE QpackInstructionField {
  QpackInstructionFieldType type;
  // For a kSbit field, |param| is a mask with exactly one bit set.
  // For kVarint fields, |param| is the prefix length of the integer encoding.
  // For kName and kValue fields, |param| is the prefix length of the length of
  // the string, and the bit immediately preceding the prefix is interpreted as
  // the Huffman bit.
  uint8_t param;
};

using QpackInstructionFields = std::vector<QpackInstructionField>;

// A QPACK instruction consists of an opcode identifying the instruction,
// followed by a non-empty list of fields.  The last field must be integer or
// string literal type to guarantee that all bytes of the instruction are
// consumed.
struct QUIC_EXPORT_PRIVATE QpackInstruction {
  QpackInstruction(const QpackInstruction&) = delete;
  const QpackInstruction& operator=(const QpackInstruction&) = delete;

  QpackInstructionOpcode opcode;
  QpackInstructionFields fields;
};

// A language is a collection of instructions.  The order does not matter.
// Every possible input must match exactly one instruction.
using QpackLanguage = std::vector<const QpackInstruction*>;

// Wire format defined in
// https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#rfc.section.5

// 5.2 Encoder stream instructions

// 5.2.1 Insert With Name Reference
const QpackInstruction* InsertWithNameReferenceInstruction();

// 5.2.2 Insert Without Name Reference
const QpackInstruction* InsertWithoutNameReferenceInstruction();

// 5.2.3 Duplicate
const QpackInstruction* DuplicateInstruction();

// 5.2.4 Dynamic Table Size Update
const QpackInstruction* SetDynamicTableCapacityInstruction();

// Encoder stream language.
const QpackLanguage* QpackEncoderStreamLanguage();

// 5.3 Decoder stream instructions

// 5.3.1 Insert Count Increment
const QpackInstruction* InsertCountIncrementInstruction();

// 5.3.2 Header Acknowledgement
const QpackInstruction* HeaderAcknowledgementInstruction();

// 5.3.3 Stream Cancellation
const QpackInstruction* StreamCancellationInstruction();

// Decoder stream language.
const QpackLanguage* QpackDecoderStreamLanguage();

// 5.4.1. Header data prefix instructions

const QpackInstruction* QpackPrefixInstruction();

const QpackLanguage* QpackPrefixLanguage();

// 5.4.2. Request and push stream instructions

// 5.4.2.1. Indexed Header Field
const QpackInstruction* QpackIndexedHeaderFieldInstruction();

// 5.4.2.2. Indexed Header Field With Post-Base Index
const QpackInstruction* QpackIndexedHeaderFieldPostBaseInstruction();

// 5.4.2.3. Literal Header Field With Name Reference
const QpackInstruction* QpackLiteralHeaderFieldNameReferenceInstruction();

// 5.4.2.4. Literal Header Field With Post-Base Name Reference
const QpackInstruction* QpackLiteralHeaderFieldPostBaseInstruction();

// 5.4.2.5. Literal Header Field Without Name Reference
const QpackInstruction* QpackLiteralHeaderFieldInstruction();

// Request and push stream language.
const QpackLanguage* QpackRequestStreamLanguage();

// Storage for instruction and field values to be encoded.
// This class can only be instantiated using factory methods that take exactly
// the arguments that the corresponding instruction needs.
class QUIC_EXPORT_PRIVATE QpackInstructionWithValues {
 public:
  // 5.2 Encoder stream instructions
  static QpackInstructionWithValues InsertWithNameReference(
      bool is_static,
      uint64_t name_index,
      absl::string_view value);
  static QpackInstructionWithValues InsertWithoutNameReference(
      absl::string_view name,
      absl::string_view value);
  static QpackInstructionWithValues Duplicate(uint64_t index);
  static QpackInstructionWithValues SetDynamicTableCapacity(uint64_t capacity);

  // 5.3 Decoder stream instructions
  static QpackInstructionWithValues InsertCountIncrement(uint64_t increment);
  static QpackInstructionWithValues HeaderAcknowledgement(uint64_t stream_id);
  static QpackInstructionWithValues StreamCancellation(uint64_t stream_id);

  // 5.4.1. Header data prefix.  Delta Base is hardcoded to be zero.
  static QpackInstructionWithValues Prefix(uint64_t required_insert_count);

  // 5.4.2. Request and push stream instructions
  static QpackInstructionWithValues IndexedHeaderField(bool is_static,
                                                       uint64_t index);
  static QpackInstructionWithValues LiteralHeaderFieldNameReference(
      bool is_static,
      uint64_t index,
      absl::string_view value);
  static QpackInstructionWithValues LiteralHeaderField(absl::string_view name,
                                                       absl::string_view value);

  const QpackInstruction* instruction() const { return instruction_; }
  bool s_bit() const { return s_bit_; }
  uint64_t varint() const { return varint_; }
  uint64_t varint2() const { return varint2_; }
  absl::string_view name() const { return name_; }
  absl::string_view value() const { return value_; }

  // Used by QpackEncoder, because in the first pass it stores absolute indices,
  // which are converted into relative indices in the second pass after base is
  // determined.
  void set_varint(uint64_t varint) { varint_ = varint; }

 private:
  friend test::QpackInstructionWithValuesPeer;

  QpackInstructionWithValues() = default;

  // |*instruction| is not owned.
  const QpackInstruction* instruction_ = nullptr;
  bool s_bit_ = false;
  uint64_t varint_ = 0;
  uint64_t varint2_ = 0;
  absl::string_view name_;
  absl::string_view value_;
};

}  // namespace quic

#endif  // QUICHE_QUIC_CORE_QPACK_QPACK_INSTRUCTIONS_H_
