// Copyright 2026 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#ifndef THIRD_PARTY_CREDENTIO_CRYPTO_CRYPTO_READ_HANDLER_H_
#define THIRD_PARTY_CREDENTIO_CRYPTO_CRYPTO_READ_HANDLER_H_

#include <cstddef>
#include <memory>
#include <string>
#include <vector>

#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include "absl/time/time.h"
#include "absl/types/span.h"
#include "crypto/algorithms.h"
#include "crypto/timestamp_read_handler.h"

namespace credentio {

// A parsed public-key certificate with optional supporting intermediate certs.
class ParsedCertificates {
 public:
  virtual ~ParsedCertificates() = default;

  // Verifies that `signature` applies to `data`, using the public key from the
  // leaf certificate. This function can be used for both claim and OCSP
  // response signatures. Performs no trust checks.
  //
  // Returns:
  //   - INVALID_ARGUMENT if the signature is invalid.
  virtual absl::Status VerifySignature(absl::string_view signature,
                                       absl::string_view data,
                                       SigningAlgorithm algorithm) const = 0;

  // Verifies the trustworthiness of the leaf certificate for claim signing, by
  // finding an ordered chain of valid certificates to a trusted root,
  // making use of the provided intermediate certificates as needed. All
  // certificate checks are performed in accordance with
  // https://spec.c2pa.org/specifications/specifications/2.4/specs/C2PA_Specification.html#_general_requirements,
  // and validity period checks are performed based on the provided time.
  //
  // Returns:
  //   - UNAUTHENTICATED if the certificate cannot be trusted.
  //   - OUT_OF_RANGE if `content_time` is outside the validity period of a
  //     certificate.
  //   - INVALID_ARGUMENT if a certificate is invalid.
  //   - UNAVAILABLE if the root trust list cannot be accessed (only possible on
  //     platforms where it is not built into the binary).
  //   - The verified trust chain from leaf to root (including the relevant
  //     trust anchor's cert) if the verification is successful.
  virtual absl::StatusOr<std::vector<std::string>> VerifyClaimSignerTrust(
      absl::Time content_time) const = 0;

  // Returns the number of certificates in the chain. Index 0 is the leaf
  // certificate, but the order of the other certificates is not guaranteed
  // and not all of them are necessarily part of the chain to a trust anchor
  // that a successful call to VerifyClaimSignerTrust finds. There is always at
  // least 1 certificate.
  virtual size_t GetCertificateCount() const = 0;

  // Returns the distinguished name of the subject of the certificate
  // (RFC 2253 format). Index 0 represents the leaf certificate.
  virtual absl::StatusOr<std::string> GetSubject(size_t index) const = 0;
  // Returns the distinguished name of the issuer of the certificate
  // (RFC 2253 format).
  virtual absl::StatusOr<std::string> GetIssuer(size_t index) const = 0;

  // Returns the certificates's start time (notBefore).
  virtual absl::StatusOr<absl::Time> GetStartTime(size_t index) const = 0;

  // Returns the certificate's end time (notAfter)
  virtual absl::StatusOr<absl::Time> GetEndTime(size_t index) const = 0;
  // Returns the certificate's serial number as a lowercase hex string.
  virtual absl::StatusOr<std::string> GetSerialNumberHex(
      size_t index) const = 0;

  // Returns the certificate's C2PA assurance level as a string (e.g.,
  // "1.3.6.1.4.1.62558.3.10"), if it is present and can be parsed.
  // This is only relevant for the leaf certificate (index 0).
  virtual absl::StatusOr<std::string> GetAssuranceLevel(size_t index) const = 0;

  // Returns the certificate's C2PA conforming product ID.
  // This is only relevant for the leaf certificate (index 0).
  virtual absl::StatusOr<std::string> GetConformingProductId(
      size_t index) const = 0;
};

// Represents the certificate revocation status returned by the OCSP
// responder, as defined in RFC 6960 (Section 2.2).
enum class OCSPRevocationStatus {
  kUnknown,  // The responder does not know the status of the certificate.
  kGood,     // The certificate is not revoked (valid).
  kRevoked,  // The certificate has been revoked.
};

// Encapsulates the crypto operation involved in claim verification.
class CryptoReadHandler : public TimestampReadHandler {
 public:
  enum class TrustEnvironment {
    kUnspecified,
    // Trust any certificates, i.e., skip claim signer and timestamp trust
    // checks.
    kAny,
    // Trust dev certificates only.
    kDevOnly,
    // Trust qual certificates for signers and prod certificates for timestamps.
    kQualOnly,
    // Trust qual and prod certificates.
    kQualAndProd,
    // Trust prod certificates only.
    kProd,
  };

  ~CryptoReadHandler() override = default;

  // Parses a set of DER-encoded certificates, the first of which is the
  // leaf certificate.
  virtual absl::StatusOr<std::unique_ptr<ParsedCertificates>>
  ParseCertificatesDer(
      absl::Span<const absl::string_view> certificates) const = 0;

  // Verifies the signature and validity of the DER-encoded OCSP response
  // against the provided issuer certificate (`issuer_certificate_der`) or
  // an authorized responder, and returns the revocation status of the target
  // certificate (`certificate_der`) at the specified verification time
  // (`verify_time`).
  //
  // The verification process ensures that the OCSP response is correctly signed
  // by the issuer or a delegated responder, conforms to RFC 6960 requirements,
  // matches the target certificate, and is valid at `verify_time`.
  //
  // Arguments:
  //   ocsp_response_der: The DER-encoded OCSP response.
  //   certificate_der: The DER-encoded X.509 certificate whose revocation
  //     status is being checked.
  //   issuer_certificate_der: The DER-encoded X.509 certificate of the issuer
  //     that signed `certificate_der`.
  //   verify_time: The time at which the OCSP response validity and revocation
  //     status are evaluated.
  //
  // Returns:
  //   - INVALID_ARGUMENT if `certificate_der`, `issuer_certificate_der`, or the
  //     OCSP response is malformed or invalid.
  //   - UNAUTHENTICATED if the OCSP response signature fails verification or
  //     if no matching response is found for `certificate_der`.
  //   - OUT_OF_RANGE if `verify_time` is outside the valid time window of the
  //     OCSP response (e.g., based on `thisUpdate` and `nextUpdate`).
  //   - The verified `OCSPRevocationStatus` (kGood, kRevoked, or kUnknown) if
  //     verification is successful.
  virtual absl::StatusOr<OCSPRevocationStatus> VerifyOcspResponse(
      absl::string_view ocsp_response_der, absl::string_view certificate_der,
      absl::string_view issuer_certificate_der,
      absl::Time verify_time) const = 0;

  // Returns the trust environment of this handler.
  virtual TrustEnvironment trust_environment() const = 0;
};

bool AbslParseFlag(absl::string_view text,
                   CryptoReadHandler::TrustEnvironment* trust,
                   std::string* error);

std::string AbslUnparseFlag(CryptoReadHandler::TrustEnvironment trust);

}  // namespace credentio

#endif  // THIRD_PARTY_CREDENTIO_CRYPTO_CRYPTO_READ_HANDLER_H_
