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

#ifndef BSSL_PKI_CERT_ISSUER_SOURCE_SYNC_UNITTEST_H_
#define BSSL_PKI_CERT_ISSUER_SOURCE_SYNC_UNITTEST_H_

#include <algorithm>

#include "cert_errors.h"
#include "cert_issuer_source.h"
#include "test_helpers.h"
#include <gtest/gtest.h>
#include <openssl/pool.h>

namespace bssl {

namespace {

::testing::AssertionResult ReadTestPem(const std::string& file_name,
                                       const std::string& block_name,
                                       std::string* result) {
  const PemBlockMapping mappings[] = {
      {block_name.c_str(), result},
  };

  return ReadTestDataFromPemFile(file_name, mappings);
}

::testing::AssertionResult ReadTestCert(
    const std::string& file_name,
    std::shared_ptr<const ParsedCertificate>* result) {
  std::string der;
  ::testing::AssertionResult r =
      ReadTestPem("testdata/cert_issuer_source_static_unittest/" + file_name,
                  "CERTIFICATE", &der);
  if (!r)
    return r;
  CertErrors errors;
  *result = ParsedCertificate::Create(
      bssl::UniquePtr<CRYPTO_BUFFER>(CRYPTO_BUFFER_new(
          reinterpret_cast<const uint8_t*>(der.data()), der.size(), nullptr)),
      {}, &errors);
  if (!*result) {
    return ::testing::AssertionFailure()
           << "ParsedCertificate::Create() failed:\n"
           << errors.ToDebugString();
  }
  return ::testing::AssertionSuccess();
}

}  // namespace

template <typename TestDelegate>
class CertIssuerSourceSyncTest : public ::testing::Test {
 public:
  void SetUp() override {
    ASSERT_TRUE(ReadTestCert("root.pem", &root_));
    ASSERT_TRUE(ReadTestCert("i1_1.pem", &i1_1_));
    ASSERT_TRUE(ReadTestCert("i1_2.pem", &i1_2_));
    ASSERT_TRUE(ReadTestCert("i2.pem", &i2_));
    ASSERT_TRUE(ReadTestCert("i3_1.pem", &i3_1_));
    ASSERT_TRUE(ReadTestCert("i3_2.pem", &i3_2_));
    ASSERT_TRUE(ReadTestCert("c1.pem", &c1_));
    ASSERT_TRUE(ReadTestCert("c2.pem", &c2_));
    ASSERT_TRUE(ReadTestCert("d.pem", &d_));
    ASSERT_TRUE(ReadTestCert("e1.pem", &e1_));
    ASSERT_TRUE(ReadTestCert("e2.pem", &e2_));
  }

  void AddCert(std::shared_ptr<const ParsedCertificate> cert) {
    delegate_.AddCert(std::move(cert));
  }

  void AddAllCerts() {
    AddCert(root_);
    AddCert(i1_1_);
    AddCert(i1_2_);
    AddCert(i2_);
    AddCert(i3_1_);
    AddCert(i3_2_);
    AddCert(c1_);
    AddCert(c2_);
    AddCert(d_);
    AddCert(e1_);
    AddCert(e2_);
  }

  CertIssuerSource& source() { return delegate_.source(); }

 protected:
  bool IssuersMatch(std::shared_ptr<const ParsedCertificate> cert,
                    ParsedCertificateList expected_matches) {
    ParsedCertificateList matches;
    source().SyncGetIssuersOf(cert.get(), &matches);

    std::vector<der::Input> der_result_matches;
    for (const auto& it : matches)
      der_result_matches.push_back(it->der_cert());
    std::sort(der_result_matches.begin(), der_result_matches.end());

    std::vector<der::Input> der_expected_matches;
    for (const auto& it : expected_matches)
      der_expected_matches.push_back(it->der_cert());
    std::sort(der_expected_matches.begin(), der_expected_matches.end());

    if (der_expected_matches == der_result_matches)
      return true;

    // Print some extra information for debugging.
    EXPECT_EQ(der_expected_matches, der_result_matches);
    return false;
  }

  TestDelegate delegate_;
  std::shared_ptr<const ParsedCertificate> root_;
  std::shared_ptr<const ParsedCertificate> i1_1_;
  std::shared_ptr<const ParsedCertificate> i1_2_;
  std::shared_ptr<const ParsedCertificate> i2_;
  std::shared_ptr<const ParsedCertificate> i3_1_;
  std::shared_ptr<const ParsedCertificate> i3_2_;
  std::shared_ptr<const ParsedCertificate> c1_;
  std::shared_ptr<const ParsedCertificate> c2_;
  std::shared_ptr<const ParsedCertificate> d_;
  std::shared_ptr<const ParsedCertificate> e1_;
  std::shared_ptr<const ParsedCertificate> e2_;
};

TYPED_TEST_SUITE_P(CertIssuerSourceSyncTest);

TYPED_TEST_P(CertIssuerSourceSyncTest, NoMatch) {
  this->AddCert(this->root_);

  EXPECT_TRUE(this->IssuersMatch(this->c1_, ParsedCertificateList()));
}

TYPED_TEST_P(CertIssuerSourceSyncTest, OneMatch) {
  this->AddAllCerts();

  EXPECT_TRUE(this->IssuersMatch(this->i1_1_, {this->root_}));
  EXPECT_TRUE(this->IssuersMatch(this->d_, {this->i2_}));
}

TYPED_TEST_P(CertIssuerSourceSyncTest, MultipleMatches) {
  this->AddAllCerts();

  EXPECT_TRUE(this->IssuersMatch(this->e1_, {this->i3_1_, this->i3_2_}));
  EXPECT_TRUE(this->IssuersMatch(this->e2_, {this->i3_1_, this->i3_2_}));
}

// Searching for the issuer of a self-issued cert returns the same cert if it
// happens to be in the CertIssuerSourceStatic.
// Conceptually this makes sense, though probably not very useful in practice.
// Doesn't hurt anything though.
TYPED_TEST_P(CertIssuerSourceSyncTest, SelfIssued) {
  this->AddAllCerts();

  EXPECT_TRUE(this->IssuersMatch(this->root_, {this->root_}));
}

// CertIssuerSourceStatic never returns results asynchronously.
TYPED_TEST_P(CertIssuerSourceSyncTest, IsNotAsync) {
  this->AddCert(this->i1_1_);
  std::unique_ptr<CertIssuerSource::Request> request;
  this->source().AsyncGetIssuersOf(this->c1_.get(), &request);
  EXPECT_EQ(nullptr, request);
}

// These are all the tests that should have the same result with or without
// normalization.
REGISTER_TYPED_TEST_SUITE_P(CertIssuerSourceSyncTest,
                            NoMatch,
                            OneMatch,
                            MultipleMatches,
                            SelfIssued,
                            IsNotAsync);

template <typename TestDelegate>
class CertIssuerSourceSyncNormalizationTest
    : public CertIssuerSourceSyncTest<TestDelegate> {};
TYPED_TEST_SUITE_P(CertIssuerSourceSyncNormalizationTest);

TYPED_TEST_P(CertIssuerSourceSyncNormalizationTest,
             MultipleMatchesAfterNormalization) {
  this->AddAllCerts();

  EXPECT_TRUE(this->IssuersMatch(this->c1_, {this->i1_1_, this->i1_2_}));
  EXPECT_TRUE(this->IssuersMatch(this->c2_, {this->i1_1_, this->i1_2_}));
}

// These tests require (utf8) normalization.
REGISTER_TYPED_TEST_SUITE_P(CertIssuerSourceSyncNormalizationTest,
                            MultipleMatchesAfterNormalization);

template <typename TestDelegate>
class CertIssuerSourceSyncNotNormalizedTest
    : public CertIssuerSourceSyncTest<TestDelegate> {};
TYPED_TEST_SUITE_P(CertIssuerSourceSyncNotNormalizedTest);

TYPED_TEST_P(CertIssuerSourceSyncNotNormalizedTest,
             OneMatchWithoutNormalization) {
  this->AddAllCerts();

  // Without normalization c1 and c2 should at least be able to find their
  // exact matching issuer. (c1 should match i1_1, and c2 should match i1_2.)
  EXPECT_TRUE(this->IssuersMatch(this->c1_, {this->i1_1_}));
  EXPECT_TRUE(this->IssuersMatch(this->c2_, {this->i1_2_}));
}

// These tests are for implementations which do not do utf8 normalization.
REGISTER_TYPED_TEST_SUITE_P(CertIssuerSourceSyncNotNormalizedTest,
                            OneMatchWithoutNormalization);

}  // namespace net

#endif  // BSSL_PKI_CERT_ISSUER_SOURCE_SYNC_UNITTEST_H_
