#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>

namespace bssl {
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);

}  // namespace bssl

#endif  // BSSL_VERIFY_H_
