// 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_TEMPLATED_CRYPTO_WRITE_HANDLER_H_
#define THIRD_PARTY_CREDENTIO_CRYPTO_TEMPLATED_CRYPTO_WRITE_HANDLER_H_

#include <cstdint>
#include <string>
#include <utility>
#include <vector>

#include "absl/base/nullability.h"
#include "absl/functional/any_invocable.h"
#include "absl/log/die_if_null.h"
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include "async/async_context.h"
#include "crypto/algorithms.h"
#include "crypto/crypto_write_handler.h"
#include "crypto/timestamp_write_handler.h"

namespace credentio {

// A FixedKeySigner that returns mock signatures for size estimation.
class TemplatedFixedKeySigner : public FixedKeySigner {
 public:
  explicit TemplatedFixedKeySigner(
      CryptoWriteHandler* absl_nonnull real_handler)
      : real_handler_(*ABSL_DIE_IF_NULL(real_handler)) {}
  SigningAlgorithm algorithm() const override {
    return real_handler_.GetSigner().algorithm();
  }
  const std::vector<std::string>& certificate_chain() const override {
    return real_handler_.GetSigner().certificate_chain();
  }
  const std::vector<std::string>& ocsp_responses() const override {
    return real_handler_.GetSigner().ocsp_responses();
  }
  uint64_t max_signature_byte_size() const override {
    return real_handler_.GetSigner().max_signature_byte_size();
  }
  absl::StatusOr<SignResponse> Sign(
      absl::string_view to_be_signed) const override {
    return SignResponse{.signature =
                            std::string(max_signature_byte_size(), '\0')};
  }

 private:
  CryptoWriteHandler& real_handler_;
};

// A CryptoWriteHandler that returns mock signatures and timestamps for size
// estimation.
class TemplatedCryptoWriteHandler : public CryptoWriteHandler {
 public:
  explicit TemplatedCryptoWriteHandler(
      CryptoWriteHandler* absl_nonnull real_handler)
      : real_handler_(*ABSL_DIE_IF_NULL(real_handler)), signer_(real_handler) {}
  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 {
    AsyncResolver<std::string>(options.async_context, std::move(cb))
        .Return(std::string(max_timestamp_byte_size(hash_algorithm), '\0'));
  }
  uint64_t max_timestamp_byte_size(
      HashAlgorithm hash_algorithm) const override {
    return real_handler_.max_timestamp_byte_size(hash_algorithm);
  }

 private:
  CryptoWriteHandler& real_handler_;
  TemplatedFixedKeySigner signer_;
};

}  // namespace credentio

#endif  // THIRD_PARTY_CREDENTIO_CRYPTO_TEMPLATED_CRYPTO_WRITE_HANDLER_H_
