// 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 "quiche/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(QpackInstructionOpcode opcode, QpackInstructionFields fields)
      : opcode(std::move(opcode)), fields(std::move(fields)) {}

  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_
