// Copyright 2014 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 "spdy/core/hpack/hpack_header_table.h"

#include <algorithm>

#include "common/platform/api/quiche_logging.h"
#include "spdy/core/hpack/hpack_constants.h"
#include "spdy/core/hpack/hpack_static_table.h"
#include "spdy/platform/api/spdy_estimate_memory_usage.h"

namespace spdy {

HpackHeaderTable::HpackHeaderTable()
    : static_entries_(ObtainHpackStaticTable().GetStaticEntries()),
      static_index_(ObtainHpackStaticTable().GetStaticIndex()),
      static_name_index_(ObtainHpackStaticTable().GetStaticNameIndex()),
      settings_size_bound_(kDefaultHeaderTableSizeSetting),
      size_(0),
      max_size_(kDefaultHeaderTableSizeSetting),
      dynamic_table_insertions_(0) {}

HpackHeaderTable::~HpackHeaderTable() = default;

size_t HpackHeaderTable::GetByName(absl::string_view name) {
  {
    auto it = static_name_index_.find(name);
    if (it != static_name_index_.end()) {
      return 1 + it->second;
    }
  }
  {
    NameToEntryMap::const_iterator it = dynamic_name_index_.find(name);
    if (it != dynamic_name_index_.end()) {
      return dynamic_table_insertions_ - it->second + kStaticTableSize;
    }
  }
  return kHpackEntryNotFound;
}

size_t HpackHeaderTable::GetByNameAndValue(absl::string_view name,
                                           absl::string_view value) {
  HpackLookupEntry query{name, value};
  {
    auto it = static_index_.find(query);
    if (it != static_index_.end()) {
      return 1 + it->second;
    }
  }
  {
    auto it = dynamic_index_.find(query);
    if (it != dynamic_index_.end()) {
      return dynamic_table_insertions_ - it->second + kStaticTableSize;
    }
  }
  return kHpackEntryNotFound;
}

void HpackHeaderTable::SetMaxSize(size_t max_size) {
  QUICHE_CHECK_LE(max_size, settings_size_bound_);

  max_size_ = max_size;
  if (size_ > max_size_) {
    Evict(EvictionCountToReclaim(size_ - max_size_));
    QUICHE_CHECK_LE(size_, max_size_);
  }
}

void HpackHeaderTable::SetSettingsHeaderTableSize(size_t settings_size) {
  settings_size_bound_ = settings_size;
  SetMaxSize(settings_size_bound_);
}

void HpackHeaderTable::EvictionSet(absl::string_view name,
                                   absl::string_view value,
                                   DynamicEntryTable::iterator* begin_out,
                                   DynamicEntryTable::iterator* end_out) {
  size_t eviction_count = EvictionCountForEntry(name, value);
  *begin_out = dynamic_entries_.end() - eviction_count;
  *end_out = dynamic_entries_.end();
}

size_t HpackHeaderTable::EvictionCountForEntry(absl::string_view name,
                                               absl::string_view value) const {
  size_t available_size = max_size_ - size_;
  size_t entry_size = HpackEntry::Size(name, value);

  if (entry_size <= available_size) {
    // No evictions are required.
    return 0;
  }
  return EvictionCountToReclaim(entry_size - available_size);
}

size_t HpackHeaderTable::EvictionCountToReclaim(size_t reclaim_size) const {
  size_t count = 0;
  for (auto it = dynamic_entries_.rbegin();
       it != dynamic_entries_.rend() && reclaim_size != 0; ++it, ++count) {
    reclaim_size -= std::min(reclaim_size, it->Size());
  }
  return count;
}

void HpackHeaderTable::Evict(size_t count) {
  for (size_t i = 0; i != count; ++i) {
    QUICHE_CHECK(!dynamic_entries_.empty());

    HpackEntry* entry = &dynamic_entries_.back();
    const size_t index = dynamic_table_insertions_ - dynamic_entries_.size();

    size_ -= entry->Size();
    auto it = dynamic_index_.find({entry->name(), entry->value()});
    QUICHE_DCHECK(it != dynamic_index_.end());
    // Only remove an entry from the index if its insertion index matches;
    // otherwise, the index refers to another entry with the same name and
    // value.
    if (it->second == index) {
      dynamic_index_.erase(it);
    }
    auto name_it = dynamic_name_index_.find(entry->name());
    QUICHE_DCHECK(name_it != dynamic_name_index_.end());
    // Only remove an entry from the literal index if its insertion index
    /// matches; otherwise, the index refers to another entry with the same
    // name.
    if (name_it->second == index) {
      dynamic_name_index_.erase(name_it);
    }
    dynamic_entries_.pop_back();
  }
}

const HpackEntry* HpackHeaderTable::TryAddEntry(absl::string_view name,
                                                absl::string_view value) {
  // Since |dynamic_entries_| has iterator stability, |name| and |value| are
  // valid even after evicting other entries and push_front() making room for
  // the new one.
  Evict(EvictionCountForEntry(name, value));

  size_t entry_size = HpackEntry::Size(name, value);
  if (entry_size > (max_size_ - size_)) {
    // Entire table has been emptied, but there's still insufficient room.
    QUICHE_DCHECK(dynamic_entries_.empty());
    QUICHE_DCHECK_EQ(0u, size_);
    return nullptr;
  }

  const size_t index = dynamic_table_insertions_;
  dynamic_entries_.push_front(
      HpackEntry(std::string(name), std::string(value)));
  HpackEntry* new_entry = &dynamic_entries_.front();
  auto index_result = dynamic_index_.insert(std::make_pair(
      HpackLookupEntry{new_entry->name(), new_entry->value()}, index));
  if (!index_result.second) {
    // An entry with the same name and value already exists in the dynamic
    // index. We should replace it with the newly added entry.
    QUICHE_DVLOG(1) << "Found existing entry at: " << index_result.first->second
                    << " replacing with: " << new_entry->GetDebugString()
                    << " at: " << index;
    QUICHE_DCHECK_GT(index, index_result.first->second);
    dynamic_index_.erase(index_result.first);
    auto insert_result = dynamic_index_.insert(std::make_pair(
        HpackLookupEntry{new_entry->name(), new_entry->value()}, index));
    QUICHE_CHECK(insert_result.second);
  }

  auto name_result =
      dynamic_name_index_.insert(std::make_pair(new_entry->name(), index));
  if (!name_result.second) {
    // An entry with the same name already exists in the dynamic index. We
    // should replace it with the newly added entry.
    QUICHE_DVLOG(1) << "Found existing entry at: " << name_result.first->second
                    << " replacing with: " << new_entry->GetDebugString()
                    << " at: " << index;
    QUICHE_DCHECK_GT(index, name_result.first->second);
    dynamic_name_index_.erase(name_result.first);
    auto insert_result =
        dynamic_name_index_.insert(std::make_pair(new_entry->name(), index));
    QUICHE_CHECK(insert_result.second);
  }

  size_ += entry_size;
  ++dynamic_table_insertions_;

  return &dynamic_entries_.front();
}

size_t HpackHeaderTable::EstimateMemoryUsage() const {
  return SpdyEstimateMemoryUsage(dynamic_entries_) +
         SpdyEstimateMemoryUsage(dynamic_index_) +
         SpdyEstimateMemoryUsage(dynamic_name_index_);
}

}  // namespace spdy
