// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/browser/code_cache/simple_lru_cache.h"

#include <limits>

#include "base/feature_list.h"
#include "base/numerics/clamped_math.h"
#include "content/public/common/content_features.h"
#include "net/base/url_util.h"

namespace content {

using GetResult = SimpleLruCache::GetResult;

GetResult::GetResult(base::Time response_time, mojo_base::BigBuffer data)
    : response_time(response_time), data(std::move(data)) {}
GetResult::~GetResult() = default;

GetResult::GetResult(GetResult&&) = default;
GetResult& GetResult::operator=(GetResult&&) = default;

SimpleLruCache::Value::Value(Age age, base::Time response_time, uint32_t size)
    : age(age), response_time(response_time), size(size) {
  DCHECK(!base::FeatureList::IsEnabled(features::kInMemoryCodeCache));
}

SimpleLruCache::Value::Value(Age age,
                             base::Time response_time,
                             uint32_t size,
                             base::span<const uint8_t> data)
    : age(age),
      response_time(response_time),
      size(size),
      data(data.begin(), data.end()) {
  DCHECK(base::FeatureList::IsEnabled(features::kInMemoryCodeCache));
}

SimpleLruCache::Value::~Value() = default;

SimpleLruCache::Value::Value(Value&&) = default;
SimpleLruCache::Value& SimpleLruCache::Value::operator=(Value&&) = default;

SimpleLruCache::SimpleLruCache(uint64_t capacity) : capacity_(capacity) {}
SimpleLruCache::~SimpleLruCache() = default;

absl::optional<GetResult> SimpleLruCache::Get(const std::string& key) {
  base::Time response_time;
  mojo_base::BigBuffer data;
  if (!GetInternal(key, &response_time, &data)) {
    return absl::nullopt;
  }
  return absl::make_optional<GetResult>(response_time, std::move(data));
}

bool SimpleLruCache::Has(const std::string& key) {
  return GetInternal(key, /*response_time=*/nullptr, /*data=*/nullptr);
}

void SimpleLruCache::Put(const std::string& key,
                         base::Time response_time,
                         base::span<const uint8_t> payload) {
  Delete(key);

  const uint64_t size = base::ClampedNumeric<uint64_t>(key.size()) +
                        payload.size() + kEmptyEntrySize;

  if (size > capacity_) {
    // Ignore a too big entry.
    return;
  }

  const Age age = GetNextAge();
  if (base::FeatureList::IsEnabled(features::kInMemoryCodeCache)) {
    entries_.emplace(key, Value(age, response_time, size, payload));
  } else {
    entries_.emplace(key, Value(age, response_time, size));
  }
  access_list_.emplace(age, std::move(key));
  size_ += size;
  Evict();
}

void SimpleLruCache::Delete(const std::string& key) {
  const auto it = entries_.find(key);
  if (it == entries_.end()) {
    return;
  }

  DCHECK_GE(size_, it->second.size);
  size_ -= it->second.size;
  access_list_.erase(it->second.age);
  entries_.erase(it);
}

uint64_t SimpleLruCache::GetSize() const {
  return size_;
}

void SimpleLruCache::Clear() {
  entries_.clear();
  access_list_.clear();
  size_ = 0;
}

bool SimpleLruCache::GetInternal(const std::string& key,
                                 base::Time* response_time,
                                 mojo_base::BigBuffer* data) {
  const auto it = entries_.find(key);
  if (it == entries_.end()) {
    return false;
  }
  const Age age = GetNextAge();
  access_list_.erase(it->second.age);
  it->second.age = age;
  access_list_.emplace(age, it->first);

  if (response_time) {
    *response_time = it->second.response_time;
  }
  if (data && base::FeatureList::IsEnabled(features::kInMemoryCodeCache)) {
    *data = mojo_base::BigBuffer(it->second.data);
  }
  return true;
}

void SimpleLruCache::Evict() {
  while (capacity_ < size_) {
    auto it = access_list_.begin();
    DCHECK(it != access_list_.end());
    DCHECK(entries_.find(it->second) != entries_.end());

    Delete(it->second);
  }
}

}  // namespace content
