// 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 "net/third_party/quiche/src/quic/test_tools/quic_crypto_server_config_peer.h"

#include "absl/strings/string_view.h"
#include "net/third_party/quiche/src/quic/test_tools/mock_clock.h"
#include "net/third_party/quiche/src/quic/test_tools/mock_random.h"
#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"

namespace quic {
namespace test {

QuicReferenceCountedPointer<QuicCryptoServerConfig::Config>
QuicCryptoServerConfigPeer::GetPrimaryConfig() {
  QuicReaderMutexLock locked(&server_config_->configs_lock_);
  return QuicReferenceCountedPointer<QuicCryptoServerConfig::Config>(
      server_config_->primary_config_);
}

QuicReferenceCountedPointer<QuicCryptoServerConfig::Config>
QuicCryptoServerConfigPeer::GetConfig(std::string config_id) {
  QuicReaderMutexLock locked(&server_config_->configs_lock_);
  if (config_id == "<primary>") {
    return QuicReferenceCountedPointer<QuicCryptoServerConfig::Config>(
        server_config_->primary_config_);
  } else {
    return server_config_->GetConfigWithScid(config_id);
  }
}

ProofSource* QuicCryptoServerConfigPeer::GetProofSource() const {
  return server_config_->proof_source_.get();
}

void QuicCryptoServerConfigPeer::ResetProofSource(
    std::unique_ptr<ProofSource> proof_source) {
  server_config_->proof_source_ = std::move(proof_source);
}

std::string QuicCryptoServerConfigPeer::NewSourceAddressToken(
    std::string config_id,
    SourceAddressTokens previous_tokens,
    const QuicIpAddress& ip,
    QuicRandom* rand,
    QuicWallTime now,
    CachedNetworkParameters* cached_network_params) {
  return server_config_->NewSourceAddressToken(*GetConfig(config_id),
                                               previous_tokens, ip, rand, now,
                                               cached_network_params);
}

HandshakeFailureReason QuicCryptoServerConfigPeer::ValidateSourceAddressTokens(
    std::string config_id,
    absl::string_view srct,
    const QuicIpAddress& ip,
    QuicWallTime now,
    CachedNetworkParameters* cached_network_params) {
  SourceAddressTokens tokens;
  HandshakeFailureReason reason = server_config_->ParseSourceAddressToken(
      *GetConfig(config_id), srct, &tokens);
  if (reason != HANDSHAKE_OK) {
    return reason;
  }

  return server_config_->ValidateSourceAddressTokens(tokens, ip, now,
                                                     cached_network_params);
}

HandshakeFailureReason
QuicCryptoServerConfigPeer::ValidateSingleSourceAddressToken(
    absl::string_view token,
    const QuicIpAddress& ip,
    QuicWallTime now) {
  SourceAddressTokens tokens;
  HandshakeFailureReason parse_status = server_config_->ParseSourceAddressToken(
      *GetPrimaryConfig(), token, &tokens);
  if (HANDSHAKE_OK != parse_status) {
    return parse_status;
  }
  EXPECT_EQ(1, tokens.tokens_size());
  return server_config_->ValidateSingleSourceAddressToken(tokens.tokens(0), ip,
                                                          now);
}

void QuicCryptoServerConfigPeer::CheckConfigs(
    std::vector<std::pair<std::string, bool>> expected_ids_and_status) {
  QuicReaderMutexLock locked(&server_config_->configs_lock_);

  ASSERT_EQ(expected_ids_and_status.size(), server_config_->configs_.size())
      << ConfigsDebug();

  for (const std::pair<
           const ServerConfigID,
           QuicReferenceCountedPointer<QuicCryptoServerConfig::Config>>& i :
       server_config_->configs_) {
    bool found = false;
    for (std::pair<ServerConfigID, bool>& j : expected_ids_and_status) {
      if (i.first == j.first && i.second->is_primary == j.second) {
        found = true;
        j.first.clear();
        break;
      }
    }

    ASSERT_TRUE(found) << "Failed to find match for " << i.first
                       << " in configs:\n"
                       << ConfigsDebug();
  }
}

// ConfigsDebug returns a std::string that contains debugging information about
// the set of Configs loaded in |server_config_| and their status.
std::string QuicCryptoServerConfigPeer::ConfigsDebug() {
  if (server_config_->configs_.empty()) {
    return "No Configs in QuicCryptoServerConfig";
  }

  std::string s;

  for (const auto& i : server_config_->configs_) {
    const QuicReferenceCountedPointer<QuicCryptoServerConfig::Config> config =
        i.second;
    if (config->is_primary) {
      s += "(primary) ";
    } else {
      s += "          ";
    }
    s += config->id;
    s += "\n";
  }

  return s;
}

void QuicCryptoServerConfigPeer::SelectNewPrimaryConfig(int seconds) {
  QuicWriterMutexLock locked(&server_config_->configs_lock_);
  server_config_->SelectNewPrimaryConfig(
      QuicWallTime::FromUNIXSeconds(seconds));
}

std::string QuicCryptoServerConfigPeer::CompressChain(
    QuicCompressedCertsCache* compressed_certs_cache,
    const QuicReferenceCountedPointer<ProofSource::Chain>& chain,
    const std::string& client_common_set_hashes,
    const std::string& client_cached_cert_hashes,
    const CommonCertSets* common_sets) {
  return QuicCryptoServerConfig::CompressChain(
      compressed_certs_cache, chain, client_common_set_hashes,
      client_cached_cert_hashes, common_sets);
}

uint32_t QuicCryptoServerConfigPeer::source_address_token_future_secs() {
  return server_config_->source_address_token_future_secs_;
}

uint32_t QuicCryptoServerConfigPeer::source_address_token_lifetime_secs() {
  return server_config_->source_address_token_lifetime_secs_;
}

}  // namespace test
}  // namespace quic
