// 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.
//

#include "crypto/templated_crypto_write_handler.h"

#include <memory>
#include <string>
#include <utility>

#include "absl/status/status_matchers.h"
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include "absl/synchronization/notification.h"
#include "absl/time/simulated_clock.h"
#include "absl/time/time.h"
#include "crypto/algorithms.h"
#include "crypto/crypto_write_handler.h"
#include "crypto/default/hasher.h"
#include "crypto/hash.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "testing/create_test_crypto_write_handler.h"

namespace credentio {
namespace {

using ::testing::ElementsAreArray;
using ::testing::IsEmpty;

absl::StatusOr<std::string> GetTimestamp(CryptoWriteHandler& handler,
                                         HashAlgorithm hash_algorithm,
                                         absl::string_view hashed_message) {
  absl::Notification done;
  absl::StatusOr<std::string> result;
  handler.CreateTimestamp(hash_algorithm, std::string(hashed_message),
                          /*options=*/{},
                          [&result, &done](absl::StatusOr<std::string> res) {
                            result = std::move(res);
                            done.Notify();
                          });
  done.WaitForNotification();
  return result;
}

TEST(TemplatedCryptoWriteHandlerTest, Create) {
  absl::StatusOr<std::unique_ptr<CryptoWriteHandler>> sign_handler =
      CreateTestCryptoWriteHandler({});
  ABSL_ASSERT_OK(sign_handler);
  TemplatedCryptoWriteHandler mock_handler(sign_handler->get());
  const FixedKeySigner& signer = (*sign_handler)->GetSigner();
  EXPECT_EQ(signer.algorithm(), mock_handler.GetSigner().algorithm());
  EXPECT_EQ(signer.max_signature_byte_size(),
            mock_handler.GetSigner().max_signature_byte_size());
  EXPECT_THAT(signer.certificate_chain(),
              ElementsAreArray(mock_handler.GetSigner().certificate_chain()));
  EXPECT_THAT(signer.ocsp_responses(),
              ElementsAreArray(mock_handler.GetSigner().ocsp_responses()));
  absl::StatusOr<SignResponse> real_signature = signer.Sign("to_be_signed");
  ABSL_ASSERT_OK(real_signature);
  absl::StatusOr<SignResponse> mock_signature =
      mock_handler.GetSigner().Sign("to_be_signed");
  ABSL_ASSERT_OK(mock_signature);
  EXPECT_EQ(mock_signature->signature.size(), signer.max_signature_byte_size());

  absl::StatusOr<std::unique_ptr<Hasher>> hasher =
      CreateHasher(HashAlgorithm::kSha384);
  ABSL_ASSERT_OK(hasher);
  (*hasher)->Update(real_signature->signature);
  std::string hashed_message = (*hasher)->Digest();
  absl::StatusOr<std::string> mock_timestamp =
      GetTimestamp(mock_handler, HashAlgorithm::kSha384, hashed_message);
  ABSL_ASSERT_OK(mock_timestamp);
  EXPECT_EQ(mock_timestamp->size(),
            (*sign_handler)->max_timestamp_byte_size(HashAlgorithm::kSha384));
}

TEST(TemplatedCryptoWriteHandlerTest, OcspExpired) {
  absl::SimulatedClock clock;
  absl::StatusOr<std::unique_ptr<CryptoWriteHandler>> sign_handler =
      CreateTestCryptoWriteHandler({.clock = &clock});
  ABSL_ASSERT_OK(sign_handler);
  TemplatedCryptoWriteHandler mock_handler(sign_handler->get());

  clock.AdvanceTime(absl::Hours(24 * 365));
  EXPECT_THAT(mock_handler.GetSigner().ocsp_responses(), IsEmpty());
}

}  // namespace
}  // namespace credentio
