// Copyright 2019 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_COMMON_STRUCTURED_HEADERS_H_
#define QUICHE_COMMON_STRUCTURED_HEADERS_H_

#include <cstddef>
#include <cstdint>
#include <map>
#include <optional>
#include <string>
#include <tuple>
#include <utility>
#include <variant>
#include <vector>

#include "absl/base/attributes.h"
#include "absl/strings/string_view.h"
#include "quiche/common/platform/api/quiche_export.h"
#include "quiche/common/platform/api/quiche_logging.h"

namespace quiche {
namespace structured_headers {

// This file implements parsing of HTTP structured headers, as defined in
// RFC8941 (https://www.rfc-editor.org/rfc/rfc8941.html). For compatibility with
// the shipped implementation of Web Packaging, this file also supports a
// previous revision of the standard, referred to here as "Draft 9".
// (https://datatracker.ietf.org/doc/draft-ietf-httpbis-header-structure/09/)
//
// The major difference between the two revisions is in the various list
// formats: Draft 9 describes "parameterised lists" and "lists-of-lists", while
// the final RFC uses a single "list" syntax, whose members may be inner lists.
// There should be no ambiguity, however, as the code which calls this parser
// should be expecting only a single type for a given header.
//
// References within the code are tagged with either [SH09] or [RFC8941],
// depending on which revision they refer to.
//
// Currently supported data types are:
//  Item:
//   integer: 123
//   string: "abc"
//   token: abc
//   byte sequence: *YWJj*
//  Parameterised list: abc_123;a=1;b=2; cdef_456, ghi;q="9";r="w"
//  List-of-lists: "foo";"bar", "baz", "bat"; "one"
//  List: "foo", "bar", "It was the best of times."
//        ("foo" "bar"), ("baz"), ("bat" "one"), ()
//        abc;a=1;b=2; cde_456, (ghi jkl);q="9";r=w
//  Dictionary: a=(1 2), b=3, c=4;aa=bb, d=(5 6);valid=?0
//
// Functions are provided to parse each of these, which are intended to be
// called with the complete value of an HTTP header (that is, any
// sub-structure will be handled internally by the parser; the exported
// functions are not intended to be called on partial header strings.) Input
// values should be ASCII byte strings (non-ASCII characters should not be
// present in Structured Header values, and will cause the entire header to fail
// to parse.)

class QUICHE_EXPORT Item {
 public:
  enum ItemType {
    kNullType,
    kIntegerType,
    kDecimalType,
    kStringType,
    kTokenType,
    kByteSequenceType,
    kBooleanType
  };
  Item();
  explicit Item(int64_t value);
  explicit Item(double value);
  explicit Item(bool value);

  // Constructors for string-like items: Strings, Tokens and Byte Sequences.
  Item(const char* value, Item::ItemType type = kStringType);
  Item(std::string value, Item::ItemType type = kStringType);

  QUICHE_EXPORT friend bool operator==(const Item&, const Item&);

  bool is_null() const { return Type() == kNullType; }
  bool is_integer() const { return Type() == kIntegerType; }
  bool is_decimal() const { return Type() == kDecimalType; }
  bool is_string() const { return Type() == kStringType; }
  bool is_token() const { return Type() == kTokenType; }
  bool is_byte_sequence() const { return Type() == kByteSequenceType; }
  bool is_boolean() const { return Type() == kBooleanType; }

  int64_t GetInteger() const {
    const auto* value = GetIfInteger();
    QUICHE_CHECK(value);
    return *value;
  }
  double GetDecimal() const {
    const auto* value = GetIfDecimal();
    QUICHE_CHECK(value);
    return *value;
  }
  bool GetBoolean() const {
    const auto* value = GetIfBoolean();
    QUICHE_CHECK(value);
    return *value;
  }

  const int64_t* GetIfInteger() const ABSL_ATTRIBUTE_LIFETIME_BOUND;
  int64_t* GetIfInteger() ABSL_ATTRIBUTE_LIFETIME_BOUND;

  const double* GetIfDecimal() const ABSL_ATTRIBUTE_LIFETIME_BOUND;
  double* GetIfDecimal() ABSL_ATTRIBUTE_LIFETIME_BOUND;

  const std::string* GetIfToken() const ABSL_ATTRIBUTE_LIFETIME_BOUND;
  std::string* GetIfToken() ABSL_ATTRIBUTE_LIFETIME_BOUND;

  // Note: This only returns a non-nullptr if `Type() == kString`, unlike the
  // deprecated `GetString()` and `TakeString()` methods.
  const std::string* GetIfString() const ABSL_ATTRIBUTE_LIFETIME_BOUND;
  std::string* GetIfString() ABSL_ATTRIBUTE_LIFETIME_BOUND;

  const std::string* GetIfByteSequence() const ABSL_ATTRIBUTE_LIFETIME_BOUND;
  std::string* GetIfByteSequence() ABSL_ATTRIBUTE_LIFETIME_BOUND;

  const bool* GetIfBoolean() const ABSL_ATTRIBUTE_LIFETIME_BOUND;
  bool* GetIfBoolean() ABSL_ATTRIBUTE_LIFETIME_BOUND;

  // Deprecated: Prefer `GetIfString()`, `GetIfToken()`, or
  // `GetIfByteSequence()`.
  const std::string& GetString() const {
    struct Visitor {
      const std::string* operator()(const std::monostate&) { return nullptr; }
      const std::string* operator()(const int64_t&) { return nullptr; }
      const std::string* operator()(const double&) { return nullptr; }
      const std::string* operator()(const std::string& value) { return &value; }
      const std::string* operator()(const Token& value) { return &value.value; }
      const std::string* operator()(const ByteSequence& value) {
        return &value.value;
      }
      const std::string* operator()(const bool&) { return nullptr; }
    };
    const std::string* value = std::visit(Visitor(), value_);
    QUICHE_CHECK(value);
    return *value;
  }

  ItemType Type() const { return static_cast<ItemType>(value_.index()); }

 private:
  friend class StructuredHeaderSerializer;

  // Wrapper types to permit simplified use of `std::visit`.
  struct Token {
    std::string value;

    friend bool operator==(const Token&, const Token&) = default;
  };

  struct ByteSequence {
    std::string value;

    friend bool operator==(const ByteSequence&, const ByteSequence&) = default;
  };

  std::variant<std::monostate, int64_t, double, std::string, Token,
               ByteSequence, bool>
      value_;
};

// Returns a human-readable representation of an ItemType.
QUICHE_EXPORT absl::string_view ItemTypeToString(Item::ItemType type);

// Returns `true` if the string is a valid Token value.
QUICHE_EXPORT bool IsValidToken(absl::string_view str);

// Holds a ParameterizedIdentifier (draft 9 only). The contained Item must be a
// Token, and there may be any number of parameters. Parameter ordering is not
// significant.
struct QUICHE_EXPORT ParameterisedIdentifier {
  using Parameters = std::map<std::string, Item, std::less<>>;

  Item identifier;
  Parameters params;

  ParameterisedIdentifier();
  ParameterisedIdentifier(const ParameterisedIdentifier&);
  ParameterisedIdentifier& operator=(const ParameterisedIdentifier&);
  ParameterisedIdentifier(Item, Parameters);
  ~ParameterisedIdentifier();

  friend bool operator==(const ParameterisedIdentifier&,
                         const ParameterisedIdentifier&) = default;
};

using Parameters = std::vector<std::pair<std::string, Item>>;

struct QUICHE_EXPORT ParameterizedItem {
  Item item;
  Parameters params;

  ParameterizedItem();
  ParameterizedItem(const ParameterizedItem&);
  ParameterizedItem& operator=(const ParameterizedItem&);
  ParameterizedItem(Item, Parameters);
  ~ParameterizedItem();

  friend bool operator==(const ParameterizedItem&,
                         const ParameterizedItem&) = default;
};

// Holds a ParameterizedMember, which may be either an single Item, or an Inner
// List of ParameterizedItems, along with any number of parameters. Parameter
// ordering is significant.
struct QUICHE_EXPORT ParameterizedMember {
  std::vector<ParameterizedItem> member;
  // If false, then |member| should only hold one Item.
  bool member_is_inner_list = false;

  Parameters params;

  ParameterizedMember();
  ParameterizedMember(const ParameterizedMember&);
  ParameterizedMember& operator=(const ParameterizedMember&);
  ParameterizedMember(std::vector<ParameterizedItem>, bool member_is_inner_list,
                      Parameters);
  // Shorthand constructor for a member which is an inner list.
  ParameterizedMember(std::vector<ParameterizedItem>, Parameters);
  // Shorthand constructor for a member which is a single Item.
  ParameterizedMember(Item, Parameters);
  ~ParameterizedMember();

  friend bool operator==(const ParameterizedMember&,
                         const ParameterizedMember&) = default;
};

using DictionaryMember = std::pair<std::string, ParameterizedMember>;

// Structured Headers RFC8941 Dictionary.
class QUICHE_EXPORT Dictionary {
 public:
  using iterator = std::vector<DictionaryMember>::iterator;
  using const_iterator = std::vector<DictionaryMember>::const_iterator;
  using key_type = std::string;
  using mapped_type = ParameterizedMember;
  using value_type = std::pair<const std::string, ParameterizedMember>;

  Dictionary();
  Dictionary(const Dictionary&);
  Dictionary(Dictionary&&);
  explicit Dictionary(std::vector<DictionaryMember> members);
  ~Dictionary();
  Dictionary& operator=(const Dictionary&) = default;
  Dictionary& operator=(Dictionary&&) = default;
  iterator begin();
  const_iterator begin() const;
  iterator end();
  const_iterator end() const;

  // operator[](size_t) and at(size_t) will both abort the program in case of
  // out of bounds access.
  ParameterizedMember& operator[](std::size_t idx);
  const ParameterizedMember& operator[](std::size_t idx) const;
  ParameterizedMember& at(std::size_t idx);
  const ParameterizedMember& at(std::size_t idx) const;

  // Consistent with std::map, if |key| does not exist in the Dictionary, then
  // operator[](absl::string_view) will create an entry for it, but at() will
  // abort the entire program.
  ParameterizedMember& operator[](absl::string_view key);
  ParameterizedMember& at(absl::string_view key);
  const ParameterizedMember& at(absl::string_view key) const;

  const_iterator find(absl::string_view key) const;
  iterator find(absl::string_view key);

  void clear();

  bool empty() const;
  std::size_t size() const;
  bool contains(absl::string_view key) const;

  friend bool operator==(const Dictionary&, const Dictionary&) = default;

 private:
  // Uses a vector to hold pairs of key and dictionary member. This makes
  // look up by index and serialization much easier.
  std::vector<DictionaryMember> members_;
};

// Structured Headers Draft 09 Parameterised List.
using ParameterisedList = std::vector<ParameterisedIdentifier>;
// Structured Headers Draft 09 List of Lists.
using ListOfLists = std::vector<std::vector<Item>>;
// Structured Headers RFC8941 List.
using List = std::vector<ParameterizedMember>;

// Returns the result of parsing the header value as an Item, if it can be
// parsed as one, or nullopt if it cannot. Note that this uses the RFC 8941
// parsing rules, and so applies tighter range limits to integers.
//
// When `strict` is true, trailing decimal points are prohibited and byte
// sequences must strictly conform to the specification.
QUICHE_EXPORT std::optional<ParameterizedItem> ParseItem(absl::string_view str,
                                                         bool strict = false);

// Returns the result of parsing the header value as an Item with no parameters,
// or nullopt if it cannot. Note that this uses the RFC 8941 parsing rules, and
// so applies tighter range limits to integers.
//
// When `strict` is true, trailing decimal points are prohibited and byte
// sequences must strictly conform to the specification.
QUICHE_EXPORT std::optional<Item> ParseBareItem(absl::string_view str,
                                                bool strict = false);

// Returns the result of parsing the header value as a Parameterised List, if it
// can be parsed as one, or nullopt if it cannot. Note that parameter keys will
// be returned as strings, which are guaranteed to be ASCII-encoded. List items,
// as well as parameter values, will be returned as Items. This method uses the
// Draft 09 parsing rules for Items, so integers have the 64-bit int range.
// Structured-Headers Draft 09 only.
QUICHE_EXPORT std::optional<ParameterisedList> ParseParameterisedList(
    absl::string_view str);

// Returns the result of parsing the header value as a List of Lists, if it can
// be parsed as one, or nullopt if it cannot. Inner list items will be returned
// as Items. This method uses the Draft 09 parsing rules for Items, so integers
// have the 64-bit int range.
// Structured-Headers Draft 09 only.
QUICHE_EXPORT std::optional<ListOfLists> ParseListOfLists(
    absl::string_view str);

// Returns the result of parsing the header value as a general List, if it can
// be parsed as one, or nullopt if it cannot. RFC 8941 only.
//
// When `strict` is true, trailing decimal points are prohibited and byte
// sequences must strictly conform to the specification.
QUICHE_EXPORT std::optional<List> ParseList(absl::string_view str,
                                            bool strict = false);

// Returns the result of parsing the header value as a general Dictionary, if it
// can be parsed as one, or nullopt if it cannot. RFC 8941 only.
//
// When `strict` is true, trailing decimal points are prohibited and byte
// sequences must strictly conform to the specification.
QUICHE_EXPORT std::optional<Dictionary> ParseDictionary(absl::string_view str,
                                                        bool strict = false);

// Serialization is implemented for RFC 8941 only.
QUICHE_EXPORT std::optional<std::string> SerializeItem(const Item& value);
QUICHE_EXPORT std::optional<std::string> SerializeItem(
    const ParameterizedItem& value);
QUICHE_EXPORT std::optional<std::string> SerializeList(const List& value);
QUICHE_EXPORT std::optional<std::string> SerializeDictionary(
    const Dictionary& value);

}  // namespace structured_headers
}  // namespace quiche

#endif  // QUICHE_COMMON_STRUCTURED_HEADERS_H_
