// 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 <string>

#include "quic/core/crypto/quic_compressed_certs_cache.h"

namespace quic {

namespace {

// Inline helper function for extending a 64-bit |seed| in-place with a 64-bit
// |value|. Based on Boost's hash_combine function.
inline void hash_combine(uint64_t* seed, const uint64_t& val) {
  (*seed) ^= val + 0x9e3779b9 + ((*seed) << 6) + ((*seed) >> 2);
}

}  // namespace

const size_t QuicCompressedCertsCache::kQuicCompressedCertsCacheSize = 225;

QuicCompressedCertsCache::UncompressedCerts::UncompressedCerts()
    : chain(nullptr),
      client_common_set_hashes(nullptr),
      client_cached_cert_hashes(nullptr) {}

QuicCompressedCertsCache::UncompressedCerts::UncompressedCerts(
    const QuicReferenceCountedPointer<ProofSource::Chain>& chain,
    const std::string* client_common_set_hashes,
    const std::string* client_cached_cert_hashes)
    : chain(chain),
      client_common_set_hashes(client_common_set_hashes),
      client_cached_cert_hashes(client_cached_cert_hashes) {}

QuicCompressedCertsCache::UncompressedCerts::~UncompressedCerts() {}

QuicCompressedCertsCache::CachedCerts::CachedCerts() {}

QuicCompressedCertsCache::CachedCerts::CachedCerts(
    const UncompressedCerts& uncompressed_certs,
    const std::string& compressed_cert)
    : chain_(uncompressed_certs.chain),
      client_common_set_hashes_(*uncompressed_certs.client_common_set_hashes),
      client_cached_cert_hashes_(*uncompressed_certs.client_cached_cert_hashes),
      compressed_cert_(compressed_cert) {}

QuicCompressedCertsCache::CachedCerts::CachedCerts(const CachedCerts& other) =
    default;

QuicCompressedCertsCache::CachedCerts::~CachedCerts() {}

bool QuicCompressedCertsCache::CachedCerts::MatchesUncompressedCerts(
    const UncompressedCerts& uncompressed_certs) const {
  return (client_common_set_hashes_ ==
              *uncompressed_certs.client_common_set_hashes &&
          client_cached_cert_hashes_ ==
              *uncompressed_certs.client_cached_cert_hashes &&
          chain_ == uncompressed_certs.chain);
}

const std::string* QuicCompressedCertsCache::CachedCerts::compressed_cert()
    const {
  return &compressed_cert_;
}

QuicCompressedCertsCache::QuicCompressedCertsCache(int64_t max_num_certs)
    : certs_cache_(max_num_certs) {}

QuicCompressedCertsCache::~QuicCompressedCertsCache() {
  // Underlying cache must be cleared before destruction.
  certs_cache_.Clear();
}

const std::string* QuicCompressedCertsCache::GetCompressedCert(
    const QuicReferenceCountedPointer<ProofSource::Chain>& chain,
    const std::string& client_common_set_hashes,
    const std::string& client_cached_cert_hashes) {
  UncompressedCerts uncompressed_certs(chain, &client_common_set_hashes,
                                       &client_cached_cert_hashes);

  uint64_t key = ComputeUncompressedCertsHash(uncompressed_certs);

  CachedCerts* cached_value = nullptr;
  auto iter = certs_cache_.Lookup(key);
  if (iter != certs_cache_.end()) {
    cached_value = iter->second.get();
  }
  if (cached_value != nullptr &&
      cached_value->MatchesUncompressedCerts(uncompressed_certs)) {
    return cached_value->compressed_cert();
  }
  return nullptr;
}

void QuicCompressedCertsCache::Insert(
    const QuicReferenceCountedPointer<ProofSource::Chain>& chain,
    const std::string& client_common_set_hashes,
    const std::string& client_cached_cert_hashes,
    const std::string& compressed_cert) {
  UncompressedCerts uncompressed_certs(chain, &client_common_set_hashes,
                                       &client_cached_cert_hashes);

  uint64_t key = ComputeUncompressedCertsHash(uncompressed_certs);

  // Insert one unit to the cache.
  std::unique_ptr<CachedCerts> cached_certs(
      new CachedCerts(uncompressed_certs, compressed_cert));
  certs_cache_.Insert(key, std::move(cached_certs));
}

size_t QuicCompressedCertsCache::MaxSize() {
  return certs_cache_.MaxSize();
}

size_t QuicCompressedCertsCache::Size() {
  return certs_cache_.Size();
}

uint64_t QuicCompressedCertsCache::ComputeUncompressedCertsHash(
    const UncompressedCerts& uncompressed_certs) {
  uint64_t hash =
      std::hash<std::string>()(*uncompressed_certs.client_common_set_hashes);
  uint64_t h =
      std::hash<std::string>()(*uncompressed_certs.client_cached_cert_hashes);
  hash_combine(&hash, h);

  hash_combine(&hash,
               reinterpret_cast<uint64_t>(uncompressed_certs.chain.get()));
  return hash;
}

}  // namespace quic
