#ifndef BSSL_VERIFY_H_
#define BSSL_VERIFY_H_

#include <chrono>
#include <optional>
#include <string>
#include <string_view>
#include <vector>

#include <openssl/pki/signature_verify_cache.h>
#include <openssl/pki/verify_error.h>

BSSL_NAMESPACE_BEGIN

class CertIssuerSourceStatic;
class TrustStoreInMemory;
class CertificateVerifyOptions;
class CertificateVerifyStatus;

class OPENSSL_EXPORT VerifyTrustStore {
 public:
  std::unique_ptr<TrustStoreInMemory> trust_store;

  ~VerifyTrustStore();

  // FromDER returns a |TrustStore| derived from interpreting the |der_certs| as
  // a bunch of DER-encoded certs, concatenated. In the event of a failure nullptr
  // e is returned and a diagnostic string is placed in |out_diagnostic|
  static std::unique_ptr<VerifyTrustStore> FromDER(
      std::string_view der_certs, std::string *out_diagnostic);

  // FromDER returns a |TrustStore| consisting of the supplied DER-encoded
  // certs in |der_certs|. In the event of a failure nullptr is returned and a
  // diagnostic string is placed in |out_diagnostic|
  static std::unique_ptr<VerifyTrustStore> FromDER(
      const std::vector<std::string_view> &der_certs,
      std::string *out_diagnostic);
};

class OPENSSL_EXPORT CertPool {
 public:
  CertPool();
  CertPool(const CertPool &) = delete;
  CertPool &operator=(const CertPool &) = delete;
  virtual ~CertPool();

  // FromCerts returns a |CertPool| consisting of the supplied DER-encoded
  // certs in |der_certs|. In the event of a failure nullptr is returned and a
  // diagnostic string is placed in |out_diagnostic|
  static std::unique_ptr<CertPool> FromCerts(
      const std::vector<std::string_view> &der_certs,
      std::string *out_diagnostic);

 private:
  friend std::optional<std::vector<std::vector<std::string>>>
  CertificateVerifyInternal(const CertificateVerifyOptions &opts,
                            VerifyError *out_error,
                            CertificateVerifyStatus *out_status,
                            bool all_paths);
  std::unique_ptr<CertIssuerSourceStatic> impl_;
};

// CertificateVerifyOptions contains all the options for a certificate verification.
class OPENSSL_EXPORT CertificateVerifyOptions {
 public:
  // The key purpose (extended key usage) to check for during verification.
  enum class KeyPurpose {
    ANY_EKU,
    SERVER_AUTH,
    CLIENT_AUTH,
    SERVER_AUTH_STRICT,
    CLIENT_AUTH_STRICT,
    SERVER_AUTH_STRICT_LEAF,
    CLIENT_AUTH_STRICT_LEAF,
  };

  CertificateVerifyOptions();
  CertificateVerifyOptions(const CertificateVerifyOptions &) = delete;
  CertificateVerifyOptions &operator=(const CertificateVerifyOptions &) =
      delete;

  KeyPurpose key_purpose = KeyPurpose::SERVER_AUTH;
  std::string_view leaf_cert;
  std::vector<std::string_view> intermediates;

  // extra_intermediates optionally points to a pool of common intermediates.
  const CertPool *extra_intermediates = nullptr;
  // trust_store points to the set of root certificates to trust.
  const VerifyTrustStore *trust_store = nullptr;
  // min_rsa_modulus_length is the minimum acceptable RSA key size in a chain.
  size_t min_rsa_modulus_length = 1024;
  // time is the time in POSIX seconds since the POSIX epoch at which to
  // validate the chain. It defaults to the current time if not set.
  std::optional<int64_t> time;
  // insecurely_allow_sha1 allows verification of signatures that use SHA-1
  // message digests.  This option is insecure and should not be used.
  bool insecurely_allow_sha1 = false;

  // max_iteration_count, if not zero, limits the number of times path building
  // will try to append an intermediate to a potential path. This bounds the
  // amount of time that a verification attempt can take, at the risk of
  // rejecting cases that would be solved if only more effort were used.
  uint32_t max_iteration_count = 0;

  // Sets an optional deadline for completing path building. It defaults
  // to std::chrono::time_point::max() if it not set. If |deadline| has a
  // value that has passed based on comparison to
  // std::chrono::steady_clock::now(), and path building has not completed,
  // path building will stop. Note that this is not a hard limit, there is no
  // guarantee how far past |deadline| time will be when path building is
  // aborted.
  std::optional<std::chrono::time_point<std::chrono::steady_clock>> deadline;

  // max_path_building_depth, if not zero, limits the depth of the path that the
  // path building algorithm attempts to build between leafs and roots. Using
  // this comes at the risk of rejecting cases that would be solved if only one
  // more certificate is added to the path.
  uint32_t max_path_building_depth = 0;

  // signature_verify_cache, if not nullptr, points to an object implementing a
  // signature verification cache derived from
  // <openssl/pki/signature_verify_cache.h>
  SignatureVerifyCache *signature_verify_cache = nullptr;
};

// CertificateVerifyStatus describes the status of a certificate verification
// attempt.
class OPENSSL_EXPORT CertificateVerifyStatus {
 public:
  CertificateVerifyStatus();

  // IterationCount returns the total number of attempted certificate additions
  // to any potential path while performing path building for verification. It
  // is the same value which may be bound by max_iteration_count in
  // CertificateVerifyOptions.
  size_t IterationCount() const;

  // MaxDepthSeen returns the maximum path depth seen during path building.
  size_t MaxDepthSeen() const;

 private:
  friend std::optional<std::vector<std::vector<std::string>>>
  CertificateVerifyInternal(const CertificateVerifyOptions &opts,
                            VerifyError *out_error,
                            CertificateVerifyStatus *out_status,
                            bool all_paths);
  size_t iteration_count_ = 0;
  size_t max_depth_seen_ = 0;
};

// Verify verifies |opts.leaf_cert| using the other values in |opts|. It
// returns either an error, or else a validated chain from leaf to root.
//
// In the event of an error return, |out_error| will be updated with information
// about the error.  It may be |nullptr|.
//
// Status information about the verification will be returned in |out_status|.
// It may be |nullptr|.
OPENSSL_EXPORT std::optional<std::vector<std::string>> CertificateVerify(
    const CertificateVerifyOptions &opts, VerifyError *out_error = nullptr,
    CertificateVerifyStatus *out_status = nullptr);

// VerifyAllPaths verifies |opts.leaf_cert| using the other values in |opts|,
// and returns all possible valid chains from the leaf to a root. If no chains
// exist, it returns an error.
OPENSSL_EXPORT std::optional<std::vector<std::vector<std::string>>>
CertificateVerifyAllPaths(const CertificateVerifyOptions &opts);

BSSL_NAMESPACE_END

#endif  // BSSL_VERIFY_H_
