// 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 "claim/timestamp_updater.h"

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

#include "absl/status/status.h"
#include "absl/status/status_macros.h"
#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/clock_interface.h"
#include "absl/time/simulated_clock.h"
#include "absl/time/time.h"
#include "async/async_context.h"
#include "constants/labels.h"
#include "cose/sig_structure.h"
#include "cose/timestamp_creator.h"
#include "crypto/crypto_read_handler.h"
#include "crypto/default/default_crypto_read_handler.h"
#include "crypto/default/hasher.h"
#include "crypto/hash.h"
#include "crypto/timestamp_write_handler.h"
#include "gmock/gmock.h"
#include "google/protobuf/timestamp.pb.h"
#include "gtest/gtest.h"
#include "jumbf/test_utils.h"
#include "proto/validation_result.pb.h"
#include "testing/create_test_crypto_write_handler.h"
#include "testing/manifest_store_test_utils.h"
#include "validator/manifest_store_validator_impl.h"
#include "validator/validator_options.h"

namespace credentio {
namespace {

using ::absl_testing::IsOkAndHolds;

constexpr absl::Time kTestTime = absl::FromUnixSeconds(1741403167);

absl::StatusOr<absl::Time> ValidateAndGetTime(
    absl::string_view manifest_store) {
  ABSL_ASSIGN_OR_RETURN(
      std::unique_ptr<CryptoReadHandler> crypto_read_handler,
      CreateDefaultCryptoReadHandler({
          .tsa_trust_anchors_pem = DefaultTestPki().root_ca.cert_pem,
          .skip_claim_signer_trust_checks_for_test = true,
      }));
  ManifestStoreValidatorImpl validator(ValidatorOptions{
      .crypto_read_handler = std::move(crypto_read_handler),
  });
  ABSL_ASSIGN_OR_RETURN(std::unique_ptr<PartialValidationResultProto> result,
                        validator.Validate(manifest_store));
  const google::protobuf::Timestamp& ts =
      result->active_manifest().claim().signature_info().timestamping_time();
  return absl::FromUnixSeconds(ts.seconds()) + absl::Nanoseconds(ts.nanos());
}

absl::StatusOr<std::unique_ptr<TimestampWriteHandler>> CreateTimestampHandler(
    absl::Clock* clock) {
  return CreateTestCryptoWriteHandler({.clock = clock});
}

absl::StatusOr<std::string> InsertTimestamp(ClaimTimestampUpdater& updater,
                                            absl::string_view manifest_store) {
  std::string updated_manifest_store(manifest_store);
  absl::Notification done;
  absl::Status status;
  updater.InsertTimestamp(&updated_manifest_store, AsyncContext(),
                          [&](absl::Status s) {
                            status = std::move(s);
                            done.Notify();
                          });
  done.WaitForNotification();
  if (!status.ok()) return status;
  return updated_manifest_store;
}

TEST(ClaimTimestampUpdater, InsertTimestampStandardManifest) {
  absl::StatusOr<std::string> manifest_store =
      CreateSimpleManifestStoreBytes({.disable_timestamping = true});
  ABSL_ASSERT_OK(manifest_store);

  absl::SimulatedClock clock;
  clock.SetTime(kTestTime);
  absl::StatusOr<std::unique_ptr<TimestampWriteHandler>> timestamp_handler =
      CreateTimestampHandler(&clock);
  ABSL_ASSERT_OK(timestamp_handler);
  auto timestamp_creator = std::make_unique<TimestampCreator>(
      timestamp_handler->get(), &DefaultHasherFactory());
  ClaimTimestampUpdater updater(std::move(timestamp_creator));
  absl::StatusOr<std::string> updated_manifest_store =
      InsertTimestamp(updater, *manifest_store);
  ABSL_ASSERT_OK(updated_manifest_store);
  EXPECT_THAT(ValidateAndGetTime(*updated_manifest_store),
              IsOkAndHolds(kTestTime));

  EXPECT_EQ(updated_manifest_store->size(), manifest_store->size());
}

TEST(ClaimTimestampUpdater, InsertTimestampInUpdateManifest) {
  absl::SimulatedClock clock;
  clock.SetTime(kTestTime);
  absl::StatusOr<std::unique_ptr<TimestampWriteHandler>> timestamp_handler =
      CreateTimestampHandler(&clock);
  ABSL_ASSERT_OK(timestamp_handler);

  std::string timestamp_placeholder(
      (*timestamp_handler)
          ->max_timestamp_byte_size(DefaultHasherFactory().algorithm()),
      '\0');
  CoseSign1TaggedStructure cose_sign1{
      .unprotected_header =
          {.sig_tst2 =
               TstContainer{.tst_tokens = {{.val = timestamp_placeholder}}}},
      .signature = "abc",
  };
  std::string claim_signature = jumbf::EncodeSuperBox(
      kClaimSignatureUuid, kClaimSignatureLabel,
      {jumbf::EncodeCborBox(EncodeCoseSign1TaggedStructure(cose_sign1))});
  std::string manifest = jumbf::EncodeSuperBox(
      kUpdateManifestUuid, "update_manifest", {claim_signature});
  std::string manifest_store = jumbf::EncodeSuperBox(
      kManifestStoreUuid, kManifestStoreLabel, {manifest});

  auto timestamp_creator = std::make_unique<TimestampCreator>(
      timestamp_handler->get(), &DefaultHasherFactory());
  ClaimTimestampUpdater updater(std::move(timestamp_creator));
  absl::StatusOr<std::string> updated_manifest_store =
      InsertTimestamp(updater, manifest_store);
  ABSL_ASSERT_OK(updated_manifest_store);

  EXPECT_EQ(updated_manifest_store->size(), manifest_store.size());
}

TEST(ClaimTimestampUpdater, TimestampExistsNoOp) {
  absl::SimulatedClock clock;
  clock.SetTime(kTestTime);
  absl::StatusOr<std::string> manifest_store = CreateSimpleManifestStoreBytes(
      {.clock = &clock, .disable_timestamping = false});
  ABSL_ASSERT_OK(manifest_store);

  clock.AdvanceTime(absl::Seconds(100));
  absl::StatusOr<std::unique_ptr<TimestampWriteHandler>> timestamp_handler =
      CreateTimestampHandler(&clock);
  ABSL_ASSERT_OK(timestamp_handler);
  auto timestamp_creator = std::make_unique<TimestampCreator>(
      timestamp_handler->get(), &DefaultHasherFactory());
  ClaimTimestampUpdater updater(std::move(timestamp_creator));
  absl::StatusOr<std::string> updated_manifest_store =
      InsertTimestamp(updater, *manifest_store);
  ABSL_ASSERT_OK(updated_manifest_store);
  EXPECT_EQ(*updated_manifest_store, *manifest_store);
}

}  // namespace
}  // namespace credentio
