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

#include <string>

#include "absl/status/status.h"
#include "absl/status/status_matchers.h"
#include "constants/labels.h"
#include "cose/sig_structure.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "jumbf/box.h"
#include "jumbf/test_utils.h"
#include "testing/jumbf_utils.h"
#include "uuid/uuid.h"

namespace credentio {
namespace {

using ::absl_testing::IsOkAndHolds;
using ::absl_testing::StatusIs;
using ::testing::HasSubstr;

TEST(ManifestStoreViewTest, WrongManifestStoreUuid) {
  std::string manifest_store = jumbf::EncodeSuperBox(
      kClaimUuid, kManifestStoreLabel, {jumbf::EncodeCborBox("")});
  EXPECT_THAT(ManifestStoreView::Create(manifest_store),
              StatusIs(absl::StatusCode::kInvalidArgument,
                       HasSubstr("No C2PA manifest store")));
}

TEST(ManifestStoreViewTest, WrongManifestStoreLabel) {
  std::string manifest_store = jumbf::EncodeSuperBox(
      kManifestStoreUuid, "wrong_label", {jumbf::EncodeCborBox("")});
  EXPECT_THAT(ManifestStoreView::Create(manifest_store),
              StatusIs(absl::StatusCode::kInvalidArgument,
                       HasSubstr("No C2PA manifest store")));
}

TEST(ManifestStoreViewTest, SingleStandardManifest) {
  std::string manifest = jumbf::EncodeSuperBox(
      kStandardManifestUuid, "manifest1", {jumbf::EncodeCborBox("")});
  std::string manifest_store = jumbf::EncodeSuperBox(
      kManifestStoreUuid, kManifestStoreLabel, {manifest});
  auto view = ManifestStoreView::Create(manifest_store);
  ABSL_ASSERT_OK(view);
  auto manifest_view = view->GetActiveManifest();
  ABSL_ASSERT_OK(manifest_view);
  EXPECT_EQ(manifest_view->label(), "manifest1");
}

TEST(ManifestStoreViewTest, MultipleManifests) {
  std::string manifest1 = jumbf::EncodeSuperBox(
      kStandardManifestUuid, "manifest1", {jumbf::EncodeCborBox("")});
  std::string manifest2 = jumbf::EncodeSuperBox(
      kStandardManifestUuid, "manifest2", {jumbf::EncodeCborBox("")});
  std::string manifest3 = jumbf::EncodeSuperBox(
      kUpdateManifestUuid, "manifest3", {jumbf::EncodeCborBox("")});
  std::string manifest_store =
      jumbf::EncodeSuperBox(kManifestStoreUuid, kManifestStoreLabel,
                            {manifest1, manifest2, manifest3});
  auto view = ManifestStoreView::Create(manifest_store);
  ABSL_ASSERT_OK(view);
  auto manifest_view = view->GetActiveManifest();
  ABSL_ASSERT_OK(manifest_view);
  EXPECT_EQ(manifest_view->label(), "manifest3");
}

TEST(ManifestStoreViewTest, NonManifestBoxesIgnored) {
  std::string manifest1 = jumbf::EncodeSuperBox(
      kStandardManifestUuid, "manifest1", {jumbf::EncodeCborBox("")});
  std::string manifest2 = jumbf::EncodeSuperBox(
      kUpdateManifestUuid, "manifest2", {jumbf::EncodeCborBox("")});
  std::string other_box1 =
      jumbf::EncodeSuperBox(UuidGenerator::Default().Generate(), "other_box1",
                            {jumbf::EncodeCborBox("")});
  std::string other_box2 =
      jumbf::EncodeSuperBox(UuidGenerator::Default().Generate(), "other_box2",
                            {jumbf::EncodeCborBox("")});
  std::string manifest_store =
      jumbf::EncodeSuperBox(kManifestStoreUuid, kManifestStoreLabel,
                            {manifest1, other_box1, manifest2, other_box2});
  auto view = ManifestStoreView::Create(manifest_store);
  ABSL_ASSERT_OK(view);
  auto manifest_view = view->GetActiveManifest();
  ABSL_ASSERT_OK(manifest_view);
  EXPECT_EQ(manifest_view->label(), "manifest2");
}

TEST(ManifestStoreViewTest, NoManifests) {
  std::string other_box1 =
      jumbf::EncodeSuperBox(UuidGenerator::Default().Generate(), "other_box1",
                            {jumbf::EncodeCborBox("")});
  std::string other_box2 =
      jumbf::EncodeSuperBox(UuidGenerator::Default().Generate(), "other_box2",
                            {jumbf::EncodeCborBox("")});
  std::string manifest_store = jumbf::EncodeSuperBox(
      kManifestStoreUuid, kManifestStoreLabel, {other_box1, other_box2});
  auto view = ManifestStoreView::Create(manifest_store);
  ABSL_ASSERT_OK(view);
  EXPECT_THAT(view->GetActiveManifest(),
              StatusIs(absl::StatusCode::kInvalidArgument,
                       HasSubstr("No active manifest found")));
}

TEST(ManifestStoreViewTest, CompressedManifestNotSupported) {
  std::string standard_manifest = jumbf::EncodeSuperBox(
      kStandardManifestUuid, "label1", {jumbf::EncodeCborBox("")});
  std::string compressed_manifest = jumbf::EncodeSuperBox(
      kCompressedManifestUuid, "label2", {jumbf::EncodeCborBox("")});
  std::string manifest_store =
      jumbf::EncodeSuperBox(kManifestStoreUuid, kManifestStoreLabel,
                            {standard_manifest, compressed_manifest});
  auto view = ManifestStoreView::Create(manifest_store);
  ABSL_ASSERT_OK(view);
  EXPECT_THAT(view->GetActiveManifest(),
              StatusIs(absl::StatusCode::kInvalidArgument,
                       HasSubstr("Compressed manifests are not supported")));
}

TEST(ManifestViewTest, NotManifest) {
  std::string encoded_box =
      jumbf::EncodeSuperBox(UuidGenerator::Default().Generate(), "other_box1",
                            {jumbf::EncodeCborBox("")});
  jumbf::SuperBox box = ParseSuperBoxOrDie(&encoded_box);
  EXPECT_THAT(ManifestView::Create(box),
              StatusIs(absl::StatusCode::kInvalidArgument,
                       HasSubstr("Not a manifest box")));
}

TEST(ManifestViewTest, WrongClaimSignatureUuid) {
  std::string claim_signature = jumbf::EncodeSuperBox(
      kClaimUuid, kClaimSignatureLabel, {jumbf::EncodeCborBox("")});
  std::string manifest = jumbf::EncodeSuperBox(
      kStandardManifestUuid, "manifest_label", {claim_signature});
  std::string manifest_store = jumbf::EncodeSuperBox(
      kManifestStoreUuid, kManifestStoreLabel, {manifest});
  auto view = ManifestStoreView::Create(manifest_store);
  ABSL_ASSERT_OK(view);
  auto manifest_view = view->GetActiveManifest();
  ABSL_ASSERT_OK(manifest_view);
  auto result = manifest_view->GetClaimSignature();
  EXPECT_THAT(result.status(),
              StatusIs(absl::StatusCode::kInvalidArgument,
                       HasSubstr("No claim signature found in the manifest")));
}

TEST(ManifestViewTest, WrongClaimSignatureLabel) {
  std::string claim_signature = jumbf::EncodeSuperBox(
      kClaimSignatureUuid, "wrong_label", {jumbf::EncodeCborBox("")});
  std::string manifest = jumbf::EncodeSuperBox(
      kStandardManifestUuid, "manifest_label", {claim_signature});
  std::string manifest_store = jumbf::EncodeSuperBox(
      kManifestStoreUuid, kManifestStoreLabel, {manifest});
  auto view = ManifestStoreView::Create(manifest_store);
  ABSL_ASSERT_OK(view);
  auto manifest_view = view->GetActiveManifest();
  ABSL_ASSERT_OK(manifest_view);
  auto result = manifest_view->GetClaimSignature();
  EXPECT_THAT(result.status(),
              StatusIs(absl::StatusCode::kInvalidArgument,
                       HasSubstr("No claim signature found in the manifest")));
}

TEST(ClaimSignatureViewTest, NotClaimSignature) {
  std::string encoded_box =
      jumbf::EncodeSuperBox(UuidGenerator::Default().Generate(), "other_box1",
                            {jumbf::EncodeCborBox("")});
  jumbf::SuperBox box = ParseSuperBoxOrDie(&encoded_box);
  EXPECT_THAT(ClaimSignatureView::Create(box),
              StatusIs(absl::StatusCode::kInvalidArgument,
                       HasSubstr("Not a claim signature box")));
}

TEST(ClaimSignatureViewTest, InvalidMultipleClaimSignature) {
  std::string claim_signature = jumbf::EncodeSuperBox(
      kClaimSignatureUuid, kClaimSignatureLabel,
      {jumbf::EncodeCborBox("abc"), jumbf::EncodeCborBox("def")});
  std::string manifest = jumbf::EncodeSuperBox(
      kStandardManifestUuid, "manifest_label", {claim_signature});
  std::string manifest_store = jumbf::EncodeSuperBox(
      kManifestStoreUuid, kManifestStoreLabel, {manifest});
  auto view = ManifestStoreView::Create(manifest_store);
  ABSL_ASSERT_OK(view);
  auto manifest_view = view->GetActiveManifest();
  ABSL_ASSERT_OK(manifest_view);
  auto claim_signature_view = manifest_view->GetClaimSignature();
  ABSL_ASSERT_OK(claim_signature_view);
  EXPECT_THAT(claim_signature_view->GetPayload(),
              StatusIs(absl::StatusCode::kInvalidArgument,
                       HasSubstr("Invalid claim signature box")));
}

TEST(ClaimSignatureViewTest, GetPayloadSuccess) {
  std::string claim_signature = jumbf::EncodeSuperBox(
      kClaimSignatureUuid, kClaimSignatureLabel, {jumbf::EncodeCborBox("abc")});
  std::string manifest = jumbf::EncodeSuperBox(
      kStandardManifestUuid, "manifest_label", {claim_signature});
  std::string manifest_store = jumbf::EncodeSuperBox(
      kManifestStoreUuid, kManifestStoreLabel, {manifest});
  auto view = ManifestStoreView::Create(manifest_store);
  ABSL_ASSERT_OK(view);
  auto manifest_view = view->GetActiveManifest();
  ABSL_ASSERT_OK(manifest_view);
  auto claim_signature_view = manifest_view->GetClaimSignature();
  ABSL_ASSERT_OK(claim_signature_view);
  EXPECT_THAT(claim_signature_view->GetPayload(), IsOkAndHolds("abc"));
}

TEST(ClaimSignatureViewTest, GetStructSuccess) {
  CoseSign1TaggedStructure cose_sign1{
      .unprotected_header = {.sig_tst2 =
                                 TstContainer{
                                     .tst_tokens = {{.val = "timestamp"}}}},
      .signature = "abc",
  };
  std::string claim_signature = jumbf::EncodeSuperBox(
      kClaimSignatureUuid, kClaimSignatureLabel,
      {jumbf::EncodeCborBox(EncodeCoseSign1TaggedStructure(cose_sign1))});
  std::string manifest = jumbf::EncodeSuperBox(
      kStandardManifestUuid, "manifest_label", {claim_signature});
  std::string manifest_store = jumbf::EncodeSuperBox(
      kManifestStoreUuid, kManifestStoreLabel, {manifest});
  auto view = ManifestStoreView::Create(manifest_store);
  ABSL_ASSERT_OK(view);
  auto manifest_view = view->GetActiveManifest();
  ABSL_ASSERT_OK(manifest_view);
  auto claim_signature_view = manifest_view->GetClaimSignature();
  ABSL_ASSERT_OK(claim_signature_view);
  EXPECT_THAT(claim_signature_view->GetStruct(), IsOkAndHolds(cose_sign1));
}

}  // namespace
}  // namespace credentio
