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

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

#include "absl/status/status.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 "cose/sig_structure.h"
#include "cose/simple_cms_parser.h"
#include "cose/timestamp_creator.h"
#include "crypto/default/hasher.h"
#include "crypto/timestamp_write_handler.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "testing/create_test_crypto_write_handler.h"
#include "tsp/parsed_timestamp_token.h"
#include "tsp/timestamp_verifier.h"
#include "tsp/verified_timestamp.h"

namespace credentio {
namespace {

using ::absl_testing::StatusIs;
using ::testing::HasSubstr;
using ::testing::IsEmpty;
using ::testing::Not;
using ::testing::SizeIs;

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

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

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

TEST(TimestampUpdater, UpdateTimestamp) {
  // Create a timestamp creator.
  absl::SimulatedClock clock;
  clock.SetTime(kTestTime);
  absl::StatusOr<std::unique_ptr<TimestampWriteHandler>> timestamp_handler =
      CreateTimestampHandler(&clock);
  ABSL_ASSERT_OK(timestamp_handler);
  TimestampCreator timestamp_creator(timestamp_handler->get(),
                                     &DefaultHasherFactory());
  TimestampUpdater timestamp_updater(&timestamp_creator);

  // Create a timestamp placeholder.
  CoseSign1TaggedStructure to_be_updated{
      .protected_header = "def",
      .unprotected_header =
          {
              .sig_tst2 = TstContainer{.tst_tokens = {{.val = std::string(
                                                           1200, '\0')}}},
              .pad = std::string(25, '\0'),
          },
      .signature = "abc",
  };
  std::string encoded_cose_sign1 =
      EncodeCoseSign1TaggedStructure(to_be_updated);
  // Update the timestamp.
  absl::StatusOr<std::string> updated_cose_sign1 =
      UpdateTimestamp(timestamp_updater, encoded_cose_sign1);
  ABSL_ASSERT_OK(updated_cose_sign1);
  EXPECT_EQ(updated_cose_sign1->size(), encoded_cose_sign1.size());

  // Verify the updated timestamp.
  TimestampVerifier verifier(/*tsa_roots=*/nullptr);
  SimpleCmsParser parser;
  absl::StatusOr<CoseSign1TaggedStructure> decoded =
      DecodeCoseSign1TaggedStructure(*updated_cose_sign1);
  ABSL_ASSERT_OK(decoded);
  ASSERT_THAT(decoded->unprotected_header.sig_tst2->tst_tokens, SizeIs(1));
  ASSERT_THAT(decoded->unprotected_header.sig_tst2->tst_tokens[0].val,
              Not(IsEmpty()));
  absl::StatusOr<std::unique_ptr<ParsedTimestampToken>> parsed_token =
      parser.ParseTimestampToken(
          decoded->unprotected_header.sig_tst2->tst_tokens[0].val);
  ABSL_ASSERT_OK(parsed_token);
  absl::StatusOr<VerifiedTimestamp> updated_verified_timestamp =
      verifier.VerifyTimestampToken(**parsed_token);
  ABSL_ASSERT_OK(updated_verified_timestamp);
  EXPECT_EQ(updated_verified_timestamp->asserted_time(), kTestTime);
}

TEST(TimestampUpdater, UpdateTimestampNotEnoughSpace) {
  // Create a timestamp creator.
  absl::SimulatedClock clock;
  clock.SetTime(kTestTime);
  absl::StatusOr<std::unique_ptr<TimestampWriteHandler>> timestamp_handler =
      CreateTimestampHandler(&clock);
  ABSL_ASSERT_OK(timestamp_handler);
  TimestampCreator timestamp_creator(timestamp_handler->get(),
                                     &DefaultHasherFactory());
  TimestampUpdater timestamp_updater(&timestamp_creator);
  // Create a timestamp.
  CoseSign1TaggedStructure cose_sign1;
  EXPECT_THAT(UpdateTimestamp(timestamp_updater,
                              EncodeCoseSign1TaggedStructure(cose_sign1)),
              StatusIs(absl::StatusCode::kInvalidArgument,
                       HasSubstr("Not enough space")));
}

}  // namespace
}  // namespace credentio
