// 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 <gtest/gtest.h>
#include <openssl/pool.h>
#include "cert_errors.h"
#include "cert_issuer_source.h"
#include "test_helpers.h"

BSSL_NAMESPACE_BEGIN

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);

BSSL_NAMESPACE_END

#endif  // BSSL_PKI_CERT_ISSUER_SOURCE_SYNC_UNITTEST_H_
