// 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_TESTING_LOCAL_KEY_CRYPTO_WRITE_HANDLER_H_
#define THIRD_PARTY_CREDENTIO_TESTING_LOCAL_KEY_CRYPTO_WRITE_HANDLER_H_

#include <cstdint>
#include <memory>
#include <optional>
#include <string>
#include <vector>

#include "absl/base/nullability.h"
#include "absl/base/thread_annotations.h"
#include "absl/container/flat_hash_map.h"
#include "absl/functional/any_invocable.h"
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include "absl/synchronization/mutex.h"
#include "absl/time/clock_interface.h"
#include "absl/time/time.h"
#include "crypto/algorithms.h"
#include "crypto/crypto_write_handler.h"
#include "crypto/timestamp_write_handler.h"
#include "tink/public_key_sign.h"

namespace credentio {

// Test signer that uses a fixed key and a caller-supplied certificate chain.
//
// To mimic OCSP responses going stale, `ocsp_responses()` returns an empty list
// once a week has passed on `clock` since construction.
//
// This class is thread-safe.
class LocalKeySigner final : public FixedKeySigner {
 public:
  // `certificate_chain` and `ocsp_responses` are DER-encoded, leaf first.
  // `clock` must outlive this object.
  LocalKeySigner(
      std::unique_ptr<crypto::tink::PublicKeySign> absl_nonnull signer,
      std::vector<std::string> certificate_chain,
      std::vector<std::string> ocsp_responses, absl::Clock* absl_nonnull clock,
      SigningAlgorithm algorithm = SigningAlgorithm::kEs256);

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

  SigningAlgorithm algorithm() const override { return algorithm_; }
  const std::vector<std::string>& certificate_chain() const override {
    return certificate_chain_;
  }
  const std::vector<std::string>& ocsp_responses() const override;
  uint64_t max_signature_byte_size() const override;
  absl::StatusOr<SignResponse> Sign(
      absl::string_view to_be_signed) const override;

 private:
  const std::unique_ptr<crypto::tink::PublicKeySign> absl_nonnull signer_;
  const std::vector<std::string> certificate_chain_;
  const std::vector<std::string> ocsp_responses_;
  absl::Clock* absl_nonnull const clock_;
  const absl::Time create_time_;
  const SigningAlgorithm algorithm_;

  mutable absl::Mutex mutex_;
  mutable std::optional<uint64_t> max_signature_byte_size_
      ABSL_GUARDED_BY(mutex_);
};

// Test implementation of CryptoWriteHandler that uses a fixed claim signer and
// a fixed timestamp signer, both supplied by the caller.
//
// For local testing only: keys are held in process memory and timestamps are
// issued locally from the supplied TSA key rather than by an RFC 3161
// time-stamping authority.
//
// This class is thread-safe.
class LocalKeyCryptoWriteHandler final : public CryptoWriteHandler {
 public:
  // `clock` must outlive this object. If `tsa_signer` is null or
  // `is_timestamping_disabled` is true, `CreateTimestamp()` fails with
  // UNAVAILABLE. `tsa_cert_pem` is the PEM-encoded certificate of `tsa_signer`.
  LocalKeyCryptoWriteHandler(
      absl::Clock* absl_nonnull clock,
      std::unique_ptr<crypto::tink::PublicKeySign> absl_nonnull signer,
      std::unique_ptr<crypto::tink::PublicKeySign> absl_nullable tsa_signer,
      bool is_timestamping_disabled, std::vector<std::string> certificate_chain,
      std::vector<std::string> ocsp_responses, SigningAlgorithm algorithm,
      std::string tsa_cert_pem,
      std::optional<absl::Time> tsa_signing_time = std::nullopt);

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

  const FixedKeySigner& GetSigner() override { return signer_; }

  void CreateTimestamp(HashAlgorithm hash_algorithm, std::string hashed_message,
                       TimestampWriteHandler::Options options,
                       absl::AnyInvocable<void(absl::StatusOr<std::string>) &&>
                           cb) const override;

  uint64_t max_timestamp_byte_size(HashAlgorithm hash_algorithm) const override;

 private:
  bool is_timestamping_enabled() const {
    return !is_timestamping_disabled_ && tsa_signer_ != nullptr;
  }

  absl::Clock* absl_nonnull const clock_;
  LocalKeySigner signer_;
  const std::unique_ptr<crypto::tink::PublicKeySign> absl_nullable tsa_signer_;
  const bool is_timestamping_disabled_;
  const std::string tsa_cert_pem_;
  const std::optional<absl::Time> tsa_signing_time_;

  mutable absl::Mutex mutex_;
  mutable absl::flat_hash_map<HashAlgorithm, uint64_t>
      max_timestamp_byte_size_map_ ABSL_GUARDED_BY(mutex_);
};

// Credentials for the test claim signer.
struct LocalKeyClaimSignerCredentials {
  // The signing key, as a PEM-encoded EC P-256 private key.
  std::string key_pem;
  // The certificate chain for `key_pem`, DER-encoded, leaf first.
  std::vector<std::string> certificate_chain;
  // DER-encoded OCSP responses covering `certificate_chain`. May be empty.
  std::vector<std::string> ocsp_responses;
};

// Credentials for the test timestamp authority.
struct LocalKeyTsaCredentials {
  // The signing key, as a PEM-encoded EC P-256 private key.
  std::string key_pem;
  // The certificate for `key_pem`, PEM-encoded.
  std::string cert_pem;
};

// Options for `CreateLocalKeyCryptoWriteHandler()`.
struct LocalKeyCryptoWriteHandlerOptions {
  // Credentials to sign claims with. Required.
  LocalKeyClaimSignerCredentials claim_signer;
  // Credentials to sign timestamps with. Required unless
  // `disable_timestamping` is true.
  LocalKeyTsaCredentials tsa;
  // The clock to read the signing and timestamping time from. It must be set
  // to a time within the validity period of the certificates above, and must
  // outlive the returned handler. If null, the real clock is used.
  absl::Clock* absl_nullable clock = nullptr;
  // If true, timestamping is disabled and returns UNAVAILABLE.
  bool disable_timestamping = false;
};

// Creates a CryptoWriteHandler that signs claims with ES256 and timestamps with
// the given test credentials. It performs no validation of its own, so the
// caller is responsible for pairing the keys with certificates that their
// verifier trusts.
absl::StatusOr<std::unique_ptr<CryptoWriteHandler>>
CreateLocalKeyCryptoWriteHandler(LocalKeyCryptoWriteHandlerOptions options);

}  // namespace credentio

#endif  // THIRD_PARTY_CREDENTIO_TESTING_LOCAL_KEY_CRYPTO_WRITE_HANDLER_H_
