// 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 "spdy/core/hpack/hpack_constants.h"
#include "spdy/core/hpack/hpack_static_table.h"
#include "spdy/platform/api/spdy_containers.h"
#include "spdy/platform/api/spdy_estimate_memory_usage.h"
#include "spdy/platform/api/spdy_logging.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),
      total_insertions_(kStaticTableSize) {}

HpackHeaderTable::~HpackHeaderTable() = default;

const HpackEntry* HpackHeaderTable::GetByIndex(size_t index) {
  if (index == 0) {
    return nullptr;
  }
  index -= 1;
  if (index < kStaticTableSize) {
    return &static_entries_[index];
  }
  index -= kStaticTableSize;
  if (index < dynamic_entries_.size()) {
    return &dynamic_entries_[index];
  }
  return nullptr;
}

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->InsertionIndex();
    }
  }
  {
    NameToEntryMap::const_iterator it = dynamic_name_index_.find(name);
    if (it != dynamic_name_index_.end()) {
      return total_insertions_ - it->second->InsertionIndex() +
             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->InsertionIndex();
    }
  }
  {
    auto it = dynamic_index_.find(query);
    if (it != dynamic_index_.end()) {
      return total_insertions_ - it->second->InsertionIndex() +
             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,
                                   EntryTable::iterator* begin_out,
                                   EntryTable::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();

    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->InsertionIndex() == entry->InsertionIndex()) {
      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->InsertionIndex() == entry->InsertionIndex()) {
      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 emplace_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;
  }
  dynamic_entries_.emplace_front(name, value, total_insertions_);
  HpackEntry* new_entry = &dynamic_entries_.front();
  auto index_result = dynamic_index_.insert(std::make_pair(
      HpackLookupEntry{new_entry->name(), new_entry->value()}, new_entry));
  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.
    SPDY_DVLOG(1) << "Found existing entry: "
                  << index_result.first->second->GetDebugString()
                  << " replacing with: " << new_entry->GetDebugString();
    QUICHE_DCHECK_GT(new_entry->InsertionIndex(),
                     index_result.first->second->InsertionIndex());
    dynamic_index_.erase(index_result.first);
    auto insert_result = dynamic_index_.insert(std::make_pair(
        HpackLookupEntry{new_entry->name(), new_entry->value()}, new_entry));
    QUICHE_CHECK(insert_result.second);
  }

  auto name_result =
      dynamic_name_index_.insert(std::make_pair(new_entry->name(), new_entry));
  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.
    SPDY_DVLOG(1) << "Found existing entry: "
                  << name_result.first->second->GetDebugString()
                  << " replacing with: " << new_entry->GetDebugString();
    QUICHE_DCHECK_GT(new_entry->InsertionIndex(),
                     name_result.first->second->InsertionIndex());
    dynamic_name_index_.erase(name_result.first);
    auto insert_result = dynamic_name_index_.insert(
        std::make_pair(new_entry->name(), new_entry));
    QUICHE_CHECK(insert_result.second);
  }

  size_ += entry_size;
  ++total_insertions_;

  return &dynamic_entries_.front();
}

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

}  // namespace spdy
