// Copyright (c) 2012 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_HTTP_HTTP_HEADER_BLOCK_H_
#define QUICHE_COMMON_HTTP_HTTP_HEADER_BLOCK_H_

#include <stddef.h>

#include <functional>
#include <list>
#include <string>
#include <utility>

#include "absl/base/attributes.h"
#include "absl/container/inlined_vector.h"
#include "absl/strings/string_view.h"
#include "quiche/common/http/http_header_storage.h"
#include "quiche/common/platform/api/quiche_export.h"
#include "quiche/common/platform/api/quiche_logging.h"
#include "quiche/common/quiche_callbacks.h"
#include "quiche/common/quiche_linked_hash_map.h"
#include "quiche/common/quiche_text_utils.h"

namespace quiche {

namespace test {
class HttpHeaderBlockPeer;
class ValueProxyPeer;
}  // namespace test

#ifndef SPDY_HEADER_DEBUG
#if !defined(NDEBUG) || defined(ADDRESS_SANITIZER)
#define SPDY_HEADER_DEBUG 1
#else  // !defined(NDEBUG) || defined(ADDRESS_SANITIZER)
#define SPDY_HEADER_DEBUG 0
#endif  // !defined(NDEBUG) || defined(ADDRESS_SANITIZER)
#endif  // SPDY_HEADER_DEBUG

// This class provides a key-value map that can be used to store SPDY header
// names and values. This data structure preserves insertion order.
//
// Under the hood, this data structure uses large, contiguous blocks of memory
// to store names and values. Lookups may be performed with absl::string_view
// keys, and values are returned as absl::string_views (via ValueProxy, below).
// Value absl::string_views are valid as long as the HttpHeaderBlock exists;
// allocated memory is never freed until HttpHeaderBlock's destruction.
//
// This implementation does not make much of an effort to minimize wasted space.
// It's expected that keys are rarely deleted from a HttpHeaderBlock.
class QUICHE_EXPORT HttpHeaderBlock {
 private:
  // Stores a list of value fragments that can be joined later with a
  // key-dependent separator.
  class QUICHE_EXPORT HeaderValue {
   public:
    HeaderValue(HttpHeaderStorage* storage, absl::string_view key,
                absl::string_view initial_value);

    // Moves are allowed.
    HeaderValue(HeaderValue&& other);
    HeaderValue& operator=(HeaderValue&& other);

    void set_storage(HttpHeaderStorage* storage);

    // Copies are not.
    HeaderValue(const HeaderValue& other) = delete;
    HeaderValue& operator=(const HeaderValue& other) = delete;

    ~HeaderValue();

    // Consumes at most |fragment.size()| bytes of memory.
    void Append(absl::string_view fragment);

    absl::string_view value() const { return as_pair().second; }
    const std::pair<absl::string_view, absl::string_view>& as_pair() const;
    absl::Span<const absl::string_view> fragments() const;

    // Size estimate including separators. Used when keys are erased from
    // HttpHeaderBlock.
    size_t SizeEstimate() const { return size_; }

   private:
    // May allocate a large contiguous region of memory to hold the concatenated
    // fragments and separators.
    absl::string_view ConsolidatedValue() const;

    mutable HttpHeaderStorage* storage_;
    mutable Fragments fragments_;
    mutable absl::string_view consolidated_;
    // The first element is the key; the second is the consolidated value.
    mutable std::pair<absl::string_view, absl::string_view> pair_;
    size_t size_ = 0;
    size_t separator_size_ = 0;
  };

  typedef quiche::QuicheLinkedHashMap<absl::string_view, HeaderValue,
                                      quiche::StringPieceCaseHash,
                                      quiche::StringPieceCaseEqual>
      MapType;

 public:
  typedef std::pair<absl::string_view, absl::string_view> value_type;

  enum class InsertResult {
    kInserted,
    kReplaced,
  };

  // Provides iteration over a sequence of std::pair<absl::string_view,
  // absl::string_view>, even though the underlying MapType::value_type is
  // different. Dereferencing the iterator will result in memory allocation for
  // multi-value headers.
  class QUICHE_EXPORT iterator {
   public:
    // The following type definitions fulfill the requirements for iterator
    // implementations.
    typedef std::pair<absl::string_view, absl::string_view> value_type;
    typedef value_type& reference;
    typedef value_type* pointer;
    typedef std::forward_iterator_tag iterator_category;
    typedef MapType::iterator::difference_type difference_type;

    // In practice, this iterator only offers access to const value_type.
    typedef const value_type& const_reference;
    typedef const value_type* const_pointer;

    explicit iterator(MapType::const_iterator it);
    iterator(const iterator& other);
    ~iterator();

    // This will result in memory allocation if the value consists of multiple
    // fragments.
    const_reference operator*() const {
#if SPDY_HEADER_DEBUG
      QUICHE_CHECK(!dereference_forbidden_);
#endif  // SPDY_HEADER_DEBUG
      return it_->second.as_pair();
    }

    const_pointer operator->() const { return &(this->operator*()); }
    bool operator==(const iterator& it) const { return it_ == it.it_; }
    bool operator!=(const iterator& it) const { return !(*this == it); }

    iterator& operator++() {
      it_++;
      return *this;
    }

    iterator operator++(int) {
      auto ret = *this;
      this->operator++();
      return ret;
    }

#if SPDY_HEADER_DEBUG
    void forbid_dereference() { dereference_forbidden_ = true; }
#endif  // SPDY_HEADER_DEBUG

   private:
    MapType::const_iterator it_;
#if SPDY_HEADER_DEBUG
    bool dereference_forbidden_ = false;
#endif  // SPDY_HEADER_DEBUG
  };
  typedef iterator const_iterator;

  HttpHeaderBlock();
  HttpHeaderBlock(const HttpHeaderBlock& other) = delete;
  HttpHeaderBlock(HttpHeaderBlock&& other);
  ~HttpHeaderBlock();

  HttpHeaderBlock& operator=(const HttpHeaderBlock& other) = delete;
  HttpHeaderBlock& operator=(HttpHeaderBlock&& other);
  HttpHeaderBlock Clone() const;

  bool operator==(const HttpHeaderBlock& other) const;
  bool operator!=(const HttpHeaderBlock& other) const;

  // Provides a human readable multi-line representation of the stored header
  // keys and values.
  std::string DebugString() const;

  iterator begin() { return wrap_iterator(map_.begin()); }
  iterator end() { return wrap_iterator(map_.end()); }
  const_iterator begin() const { return wrap_const_iterator(map_.begin()); }
  const_iterator end() const { return wrap_const_iterator(map_.end()); }
  bool empty() const { return map_.empty(); }
  size_t size() const { return map_.size(); }
  iterator find(absl::string_view key) { return wrap_iterator(map_.find(key)); }
  const_iterator find(absl::string_view key) const {
    return wrap_const_iterator(map_.find(key));
  }
  bool contains(absl::string_view key) const { return find(key) != end(); }
  void erase(absl::string_view key);

  // Clears both our MapType member and the memory used to hold headers.
  void clear();

  // The next few methods copy data into our backing storage.

  // If key already exists in the block, replaces the value of that key and
  // returns `kReplaced`. Else adds a new header to the end of the block and
  // returns `kInserted`.
  InsertResult insert(const value_type& value);

  // If a header with the key is already present, then append the value to the
  // existing header value, NUL ("\0") separated unless the key is cookie, in
  // which case the separator is "; ".
  // If there is no such key, a new header with the key and value is added.
  void AppendValueOrAddHeader(const absl::string_view key,
                              const absl::string_view value);

  // This object provides automatic conversions that allow HttpHeaderBlock to
  // be nearly a drop-in replacement for a linked hash map with string keys and
  // values.  It reads data from or writes data to a HttpHeaderStorage.
  class QUICHE_EXPORT ValueProxy {
   public:
    ~ValueProxy();

    // Moves are allowed.
    ValueProxy(ValueProxy&& other);
    ValueProxy& operator=(ValueProxy&& other);

    // Copies are not.
    ValueProxy(const ValueProxy& other) = delete;
    ValueProxy& operator=(const ValueProxy& other) = delete;

    // Assignment modifies the underlying HttpHeaderBlock.
    ValueProxy& operator=(absl::string_view value);

    // Provides easy comparison against absl::string_view.
    bool operator==(absl::string_view value) const;

    std::string as_string() const;

   private:
    friend class HttpHeaderBlock;
    friend class test::ValueProxyPeer;

    ValueProxy(HttpHeaderBlock* block,
               HttpHeaderBlock::MapType::iterator lookup_result,
               const absl::string_view key,
               size_t* spdy_header_block_value_size);

    HttpHeaderBlock* block_;
    HttpHeaderBlock::MapType::iterator lookup_result_;
    absl::string_view key_;
    size_t* spdy_header_block_value_size_;
    bool valid_;
  };

  // Allows either lookup or mutation of the value associated with a key.
  ABSL_MUST_USE_RESULT ValueProxy operator[](const absl::string_view key);

  // The function is invoked on each (name, value) pair, where individual value
  // fragments receive their own invocation.
  void ForEach(
      quiche::UnretainedCallback<void(absl::string_view, absl::string_view)> fn)
      const;

  size_t TotalBytesUsed() const { return key_size_ + value_size_; }

 private:
  friend class test::HttpHeaderBlockPeer;

  inline iterator wrap_iterator(MapType::const_iterator inner_iterator) const {
#if SPDY_HEADER_DEBUG
    iterator outer_iterator(inner_iterator);
    if (inner_iterator == map_.end()) {
      outer_iterator.forbid_dereference();
    }
    return outer_iterator;
#else   // SPDY_HEADER_DEBUG
    return iterator(inner_iterator);
#endif  // SPDY_HEADER_DEBUG
  }

  inline const_iterator wrap_const_iterator(
      MapType::const_iterator inner_iterator) const {
#if SPDY_HEADER_DEBUG
    const_iterator outer_iterator(inner_iterator);
    if (inner_iterator == map_.end()) {
      outer_iterator.forbid_dereference();
    }
    return outer_iterator;
#else   // SPDY_HEADER_DEBUG
    return iterator(inner_iterator);
#endif  // SPDY_HEADER_DEBUG
  }

  void AppendHeader(const absl::string_view key, const absl::string_view value);
  absl::string_view WriteKey(const absl::string_view key);
  size_t bytes_allocated() const;

  // absl::string_views held by |map_| point to memory owned by |storage_|.
  MapType map_;
  HttpHeaderStorage storage_;

  size_t key_size_ = 0;
  size_t value_size_ = 0;
};

inline bool operator==(absl::string_view lhs,
                       const HttpHeaderBlock::ValueProxy& rhs) {
  return rhs == lhs;
}

}  // namespace quiche

#endif  // QUICHE_COMMON_HTTP_HTTP_HEADER_BLOCK_H_
