// Copyright 2026 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_QUICHE_STRING_TUPLE_H_
#define QUICHE_COMMON_QUICHE_STRING_TUPLE_H_

#include <algorithm>
#include <cstddef>
#include <cstdint>
#include <initializer_list>
#include <iterator>
#include <limits>
#include <optional>
#include <string>
#include <type_traits>
#include <vector>

#include "absl/base/attributes.h"
#include "absl/container/inlined_vector.h"
#include "absl/strings/escaping.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_format.h"
#include "absl/strings/str_join.h"
#include "absl/strings/string_view.h"
#include "quiche/common/platform/api/quiche_bug_tracker.h"
#include "quiche/common/platform/api/quiche_export.h"

namespace quiche {

// Flexible container for storing tuples of potentially small strings.  Allows
// the maximum byte size of the string to be specified at the compile-time; the
// specified size can be used to optimize the data layout of the container.
//
// Note that the limit in question is the limit on the number of string bytes;
// as empty elements are allowed, the number of tuple elements can be
// potentially unlimited.
template <size_t MaxDataSize = std::numeric_limits<size_t>::max(),
          size_t InlinedSizes = 4>
class QUICHE_NO_EXPORT QuicheStringTuple {
 private:
  // Use the information about the maximum size of the tuple to pick the
  // smallest possible offset type.
  using OffsetT = std::conditional_t<
      MaxDataSize <= 0xffff, uint16_t,
      std::conditional_t<MaxDataSize <= 0xffffffff, uint32_t, uint64_t> >;

  // Basic read-only proxy iterator over the string tuple.  Invalidated on any
  // removal of elements from the tuple.
  class TupleIterator {
   public:
    using value_type = absl::string_view;
    using difference_type = std::ptrdiff_t;
    using reference = value_type&;
    using iterator_category = std::input_iterator_tag;

    TupleIterator(const TupleIterator&) = default;
    TupleIterator(TupleIterator&&) = default;
    TupleIterator& operator=(const TupleIterator&) = default;
    TupleIterator& operator=(TupleIterator&&) = default;

    absl::string_view operator*() const { return (*tuple_)[offset_]; }

    TupleIterator& operator++() {
      ++offset_;
      return *this;
    }
    TupleIterator operator++(int) {
      ++offset_;
      return TupleIterator(tuple_, offset_ - 1);
    }
    TupleIterator& operator--() {
      --offset_;
      return *this;
    }
    TupleIterator operator--(int) {
      --offset_;
      return TupleIterator(tuple_, offset_ + 1);
    }

    bool operator==(const TupleIterator&) const = default;
    bool operator!=(const TupleIterator&) const = default;

   private:
    friend class QuicheStringTuple;

    TupleIterator(const QuicheStringTuple* tuple, size_t offset)
        : tuple_(tuple), offset_(offset) {}

    const QuicheStringTuple* tuple_;
    OffsetT offset_;
  };

 public:
  using value_type = absl::string_view;
  using reference = value_type&;
  using const_reference = const value_type&;
  using iterator = TupleIterator;
  using const_iterator = TupleIterator;

  static constexpr size_t kMaxDataSize = MaxDataSize;

  QuicheStringTuple() = default;
  QuicheStringTuple(const QuicheStringTuple&) noexcept = default;
  QuicheStringTuple(QuicheStringTuple&&) noexcept = default;
  QuicheStringTuple& operator=(const QuicheStringTuple&) noexcept = default;
  QuicheStringTuple& operator=(QuicheStringTuple&&) noexcept = default;

  // Convenience constructor meant for constants. Will QUIC_BUG if adding any of
  // the elements fails.
  explicit QuicheStringTuple(
      std::initializer_list<const absl::string_view> items) {
    ReserveTupleElements(items.size());
    for (absl::string_view item : items) {
      bool success = Add(item);
      QUICHE_BUG_IF(QuicheStringTuple_initializer_list_too_large, !success)
          << "Attempted to use initializer list constructor for "
             "QuicheStringTuple with a string that exceeds the specified "
             "maximum size";
    }
  }

  // Adds a new string to the end of the tuple. Returns false if this operation
  // results in the size limit being exceeded.
  [[nodiscard]] bool Add(absl::string_view element) {
    if (element.size() + data_.size() > kMaxDataSize) {
      return false;
    }
    elements_start_offsets_.push_back(data_.size());
    data_.append(element.data(), element.size());
    return true;
  }

  // Removes an element from the end of the tuple, if there are any.
  bool Pop() {
    if (empty()) {
      return false;
    }
    data_.resize(elements_start_offsets_.back());
    elements_start_offsets_.pop_back();
    return true;
  }

  // Removes all elements from the tuple.
  void Clear() {
    data_.clear();
    elements_start_offsets_.clear();
  }

  // Returns the string at the offset `i`, or nullopt if `i` is out of bounds.
  std::optional<absl::string_view> ValueAt(size_t i) const
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
    if (i >= elements_start_offsets_.size()) {
      return std::nullopt;
    }
    if (i == elements_start_offsets_.size() - 1) {
      return absl::string_view(data_).substr(elements_start_offsets_[i]);
    }
    const size_t start = elements_start_offsets_[i];
    const size_t end = elements_start_offsets_[i + 1];
    return absl::string_view(data_).substr(start, end - start);
  }

  // Returns the string at the offset `i`; QUICHE_BUGs if `i` is out of bounds
  // and returns an empty string.
  absl::string_view operator[](size_t i) const {
    auto result = ValueAt(i);
    if (!result.has_value()) {
      QUICHE_BUG(QuicheStringTuple_oob_access)
          << "Tried to access an out-of-bounds element #" << i
          << " for a string tuple of size " << size();
      return absl::string_view();
    }
    return *result;
  }

  // Allows pre-allocating memory if the total byte size of the tuple and the
  // number of elements in it are known in advance.
  void ReserveDataBytes(size_t n) { data_.reserve(n); }
  void ReserveTupleElements(size_t n) { elements_start_offsets_.reserve(n); }

  // Returns true if the specified tuple is a prefix of (or is equal to) this
  // tuple.
  bool IsPrefix(const QuicheStringTuple& other) const {
    return other.size() <= size() &&
           std::equal(iterator(this, 0), iterator(this, other.size()),
                      other.begin());
  }

  bool empty() const { return elements_start_offsets_.empty(); }
  size_t size() const { return elements_start_offsets_.size(); }
  size_t TotalBytes() const { return data_.size(); }
  size_t BytesLeft() const { return kMaxDataSize - data_.size(); }

  iterator begin() const { return iterator(this, 0); }
  iterator end() const { return iterator(this, size()); }

  // Tuples are lexicographical ordered.
  auto operator<=>(const QuicheStringTuple& other) const {
    return std::lexicographical_compare_three_way(begin(), end(), other.begin(),
                                                  other.end());
  }
  bool operator==(const QuicheStringTuple& other) const = default;

  template <typename H>
  friend H AbslHashValue(H h, const QuicheStringTuple& tuple) {
    return H::combine(std::move(h), tuple.data_, tuple.elements_start_offsets_);
  }

  // String tuple pretty-printer primarily meant for debugging purposes.
  template <typename Sink>
  friend void AbslStringify(Sink& sink, const QuicheStringTuple& tuple) {
    std::vector<std::string> bits;
    bits.reserve(tuple.size());
    for (absl::string_view element : tuple) {
      bits.push_back(absl::StrCat("\"", absl::CHexEscape(element), "\""));
    }
    absl::Format(&sink, "{%s}", absl::StrJoin(bits, ", "));
  }

 private:
  std::string data_;
  absl::InlinedVector<OffsetT, InlinedSizes> elements_start_offsets_;
};

static_assert(std::input_iterator<QuicheStringTuple<>::iterator>);

}  // namespace quiche

#endif  // QUICHE_COMMON_QUICHE_STRING_TUPLE_H_
