// Copyright 2016 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.

#include "http2/hpack/decoder/hpack_decoder_tables.h"

#include "absl/strings/str_cat.h"
#include "http2/hpack/http2_hpack_constants.h"
#include "http2/platform/api/http2_logging.h"

namespace http2 {
namespace {

std::vector<HpackStringPair>* MakeStaticTable() {
  auto* ptr = new std::vector<HpackStringPair>();
  ptr->reserve(kFirstDynamicTableIndex);
  ptr->emplace_back("", "");

#define STATIC_TABLE_ENTRY(name, value, index)               \
  QUICHE_DCHECK_EQ(ptr->size(), static_cast<size_t>(index)); \
  ptr->emplace_back(name, value)

#include "http2/hpack/hpack_static_table_entries.inc"

#undef STATIC_TABLE_ENTRY

  return ptr;
}

const std::vector<HpackStringPair>* GetStaticTable() {
  static const std::vector<HpackStringPair>* const g_static_table =
      MakeStaticTable();
  return g_static_table;
}

}  // namespace

HpackStringPair::HpackStringPair(std::string name, std::string value)
    : name(std::move(name)), value(std::move(value)) {
  HTTP2_DVLOG(3) << DebugString() << " ctor";
}

HpackStringPair::~HpackStringPair() {
  HTTP2_DVLOG(3) << DebugString() << " dtor";
}

std::string HpackStringPair::DebugString() const {
  return absl::StrCat("HpackStringPair(name=", name, ", value=", value, ")");
}

std::ostream& operator<<(std::ostream& os, const HpackStringPair& p) {
  os << p.DebugString();
  return os;
}

HpackDecoderStaticTable::HpackDecoderStaticTable(
    const std::vector<HpackStringPair>* table)
    : table_(table) {}

HpackDecoderStaticTable::HpackDecoderStaticTable() : table_(GetStaticTable()) {}

const HpackStringPair* HpackDecoderStaticTable::Lookup(size_t index) const {
  if (0 < index && index < kFirstDynamicTableIndex) {
    return &((*table_)[index]);
  }
  return nullptr;
}

HpackDecoderDynamicTable::HpackDecoderDynamicTable()
    : insert_count_(kFirstDynamicTableIndex - 1) {}
HpackDecoderDynamicTable::~HpackDecoderDynamicTable() = default;

void HpackDecoderDynamicTable::DynamicTableSizeUpdate(size_t size_limit) {
  HTTP2_DVLOG(3) << "HpackDecoderDynamicTable::DynamicTableSizeUpdate "
                 << size_limit;
  EnsureSizeNoMoreThan(size_limit);
  QUICHE_DCHECK_LE(current_size_, size_limit);
  size_limit_ = size_limit;
}

// TODO(jamessynge): Check somewhere before here that names received from the
// peer are valid (e.g. are lower-case, no whitespace, etc.).
void HpackDecoderDynamicTable::Insert(std::string name, std::string value) {
  HpackStringPair entry(std::move(name), std::move(value));
  size_t entry_size = entry.size();
  HTTP2_DVLOG(2) << "InsertEntry of size=" << entry_size
                 << "\n     name: " << entry.name
                 << "\n    value: " << entry.value;
  if (entry_size > size_limit_) {
    HTTP2_DVLOG(2) << "InsertEntry: entry larger than table, removing "
                   << table_.size() << " entries, of total size "
                   << current_size_ << " bytes.";
    table_.clear();
    current_size_ = 0;
    return;
  }
  ++insert_count_;
  size_t insert_limit = size_limit_ - entry_size;
  EnsureSizeNoMoreThan(insert_limit);
  table_.push_front(entry);
  current_size_ += entry_size;
  HTTP2_DVLOG(2) << "InsertEntry: current_size_=" << current_size_;
  QUICHE_DCHECK_GE(current_size_, entry_size);
  QUICHE_DCHECK_LE(current_size_, size_limit_);
}

const HpackStringPair* HpackDecoderDynamicTable::Lookup(size_t index) const {
  if (index < table_.size()) {
    return &table_[index];
  }
  return nullptr;
}

void HpackDecoderDynamicTable::EnsureSizeNoMoreThan(size_t limit) {
  HTTP2_DVLOG(2) << "EnsureSizeNoMoreThan limit=" << limit
                 << ", current_size_=" << current_size_;
  // Not the most efficient choice, but any easy way to start.
  while (current_size_ > limit) {
    RemoveLastEntry();
  }
  QUICHE_DCHECK_LE(current_size_, limit);
}

void HpackDecoderDynamicTable::RemoveLastEntry() {
  QUICHE_DCHECK(!table_.empty());
  if (!table_.empty()) {
    HTTP2_DVLOG(2) << "RemoveLastEntry current_size_=" << current_size_
                   << ", last entry size=" << table_.back().size();
    QUICHE_DCHECK_GE(current_size_, table_.back().size());
    current_size_ -= table_.back().size();
    table_.pop_back();
    // Empty IFF current_size_ == 0.
    QUICHE_DCHECK_EQ(table_.empty(), current_size_ == 0);
  }
}

HpackDecoderTables::HpackDecoderTables() = default;
HpackDecoderTables::~HpackDecoderTables() = default;

const HpackStringPair* HpackDecoderTables::Lookup(size_t index) const {
  if (index < kFirstDynamicTableIndex) {
    return static_table_.Lookup(index);
  } else {
    return dynamic_table_.Lookup(index - kFirstDynamicTableIndex);
  }
}

}  // namespace http2
