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

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

  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_
