// 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::IsOk;
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);
  ASSERT_THAT(view, IsOk());
  auto manifest_view = view->GetActiveManifest();
  ASSERT_THAT(manifest_view, IsOk());
  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);
  ASSERT_THAT(view, IsOk());
  auto manifest_view = view->GetActiveManifest();
  ASSERT_THAT(manifest_view, IsOk());
  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);
  ASSERT_THAT(view, IsOk());
  auto manifest_view = view->GetActiveManifest();
  ASSERT_THAT(manifest_view, IsOk());
  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);
  ASSERT_THAT(view, IsOk());
  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);
  ASSERT_THAT(view, IsOk());
  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);
  ASSERT_THAT(view, IsOk());
  auto manifest_view = view->GetActiveManifest();
  ASSERT_THAT(manifest_view, IsOk());
  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);
  ASSERT_THAT(view, IsOk());
  auto manifest_view = view->GetActiveManifest();
  ASSERT_THAT(manifest_view, IsOk());
  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);
  ASSERT_THAT(view, IsOk());
  auto manifest_view = view->GetActiveManifest();
  ASSERT_THAT(manifest_view, IsOk());
  auto claim_signature_view = manifest_view->GetClaimSignature();
  ASSERT_THAT(claim_signature_view, IsOk());
  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);
  ASSERT_THAT(view, IsOk());
  auto manifest_view = view->GetActiveManifest();
  ASSERT_THAT(manifest_view, IsOk());
  auto claim_signature_view = manifest_view->GetClaimSignature();
  ASSERT_THAT(claim_signature_view, IsOk());
  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);
  ASSERT_THAT(view, IsOk());
  auto manifest_view = view->GetActiveManifest();
  ASSERT_THAT(manifest_view, IsOk());
  auto claim_signature_view = manifest_view->GetClaimSignature();
  ASSERT_THAT(claim_signature_view, IsOk());
  EXPECT_THAT(claim_signature_view->GetStruct(), IsOkAndHolds(cose_sign1));
}

}  // namespace
}  // namespace credentio
