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

#include <cstdint>
#include <string>
#include <utility>
#include <vector>

#include "absl/status/status_matchers.h"
#include "absl/status/statusor.h"
#include "absl/strings/escaping.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "constants/labels.h"
#include "cppbor/cppbor.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "jumbf/constants.h"
#include "jumbf/test_utils.h"
#include "nlohmann/json.hpp"
#include "proto/ingredient_assertion.pb.h"
#include "proto/ingredient_validation_result.pb.h"
#include "proto/manifest.pb.h"
#include "proto/validation_result.pb.h"
#include "proto/validation_status.pb.h"

namespace credentio {
namespace {

using ::absl_testing::IsOk;

TEST(ConvertManifestStoreToCrJsonTest, ByteStringsAreBase64Encoded) {
  // 1. Construct a CBOR map containing a byte string.
  cppbor::Map map;
  map.add("hash_value", cppbor::Bstr("raw_bytes_here"));
  std::vector<uint8_t> encoded_cbor = map.encode();
  absl::string_view cbor_view(
      reinterpret_cast<const char*>(encoded_cbor.data()), encoded_cbor.size());

  // 2. Wrap it in a CborBox.
  std::string cbor_box = jumbf::EncodeCborBox(cbor_view);

  // 3. Wrap that in a SuperBox (representing an assertion).
  // Use a standard allowlisted assertion label, e.g., kDataHashAssertionLabel.
  std::string assertion_box = jumbf::EncodeSuperBox(
      jumbf::kCborBoxTypeUuid, kDataHashAssertionLabel, {cbor_box},
      /*requestable=*/true);

  // 4. Wrap that in an assertion store SuperBox.
  std::string assertion_store_box = jumbf::EncodeSuperBox(
      kAssertionStoreUuid, kAssertionStoreLabel, {assertion_box});

  // 5. Wrap that in a manifest SuperBox.
  std::string manifest_box = jumbf::EncodeSuperBox(
      kStandardManifestUuid, "test_manifest", {assertion_store_box});

  // 6. Wrap that in a manifest store SuperBox.
  std::string manifest_store_box = jumbf::EncodeSuperBox(
      kManifestStoreUuid, kManifestStoreLabel, {manifest_box});

  // 7. Call ConvertManifestStoreToCrJsonWithoutValidationResults.
  absl::StatusOr<nlohmann::json> j =
      ConvertToCrJsonWithoutValidationResults(manifest_store_box);
  ASSERT_THAT(j, IsOk());

  // 8. Verify that the output JSON contains the base64 encoded byte string.
  // The expected format is "b64'<base64_data>'".
  std::string expected_b64 =
      absl::StrCat("b64'", absl::Base64Escape("raw_bytes_here"), "'");
  ASSERT_TRUE(j->contains("manifests"));
  ASSERT_GT((*j)["manifests"].size(), 0);
  const auto& manifest = (*j)["manifests"][0];
  ASSERT_TRUE(manifest.contains("assertions"));
  const auto& assertions = manifest["assertions"];
  ASSERT_TRUE(assertions.contains(kDataHashAssertionLabel));
  const auto& assertion_json = assertions[kDataHashAssertionLabel];

  EXPECT_EQ(assertion_json["hash_value"], expected_b64);
}

TEST(ConvertManifestStoreToCrJsonTest, UnrecognizedAssertionIsIncluded) {
  // 1. Construct a CBOR map for a dummy assertion.
  cppbor::Map map;
  map.add("foo", "bar");
  std::vector<uint8_t> encoded_cbor = map.encode();
  absl::string_view cbor_view(
      reinterpret_cast<const char*>(encoded_cbor.data()), encoded_cbor.size());

  // 2. Wrap it in a CborBox.
  std::string cbor_box = jumbf::EncodeCborBox(cbor_view);

  // 3. Wrap that in a SuperBox with an unrecognized label.
  std::string assertion_box = jumbf::EncodeSuperBox(
      jumbf::kCborBoxTypeUuid, "custom.unrecognized.assertion", {cbor_box},
      /*requestable=*/true);

  // 4. Wrap that in an assertion store SuperBox.
  std::string assertion_store_box = jumbf::EncodeSuperBox(
      kAssertionStoreUuid, kAssertionStoreLabel, {assertion_box});

  // 5. Wrap that in a manifest SuperBox.
  std::string manifest_box = jumbf::EncodeSuperBox(
      kStandardManifestUuid, "test_manifest", {assertion_store_box});

  // 6. Wrap that in a manifest store SuperBox.
  std::string manifest_store_box = jumbf::EncodeSuperBox(
      kManifestStoreUuid, kManifestStoreLabel, {manifest_box});

  // 7. Call ConvertManifestStoreToCrJsonWithoutValidationResults.
  absl::StatusOr<nlohmann::json> j =
      ConvertToCrJsonWithoutValidationResults(manifest_store_box);
  ASSERT_THAT(j, IsOk());

  // 8. Verify that the output JSON contains the unrecognized assertion with
  // empty object.
  ASSERT_TRUE(j->contains("manifests"));
  ASSERT_GT((*j)["manifests"].size(), 0);
  const auto& manifest = (*j)["manifests"][0];
  ASSERT_TRUE(manifest.contains("assertions"));
  const auto& assertions = manifest["assertions"];
  ASSERT_TRUE(assertions.contains("custom.unrecognized.assertion"));
  EXPECT_TRUE(assertions["custom.unrecognized.assertion"].is_object());
  EXPECT_TRUE(assertions["custom.unrecognized.assertion"].empty());
}

TEST(ConvertManifestStoreToCrJsonTest, HandlesNonSuperBoxInAssertionStore) {
  // 1. Construct a CBOR box directly. This is not a SuperBox.
  std::string cbor_box = jumbf::EncodeCborBox("test");

  // 2. Wrap that in an assertion store SuperBox. This is the error condition.
  std::string assertion_store_box = jumbf::EncodeSuperBox(
      kAssertionStoreUuid, kAssertionStoreLabel, {cbor_box});

  // 3. Wrap that in a manifest SuperBox.
  std::string manifest_box = jumbf::EncodeSuperBox(
      kStandardManifestUuid, "test_manifest", {assertion_store_box});

  // 4. Wrap that in a manifest store SuperBox.
  std::string manifest_store_box = jumbf::EncodeSuperBox(
      kManifestStoreUuid, kManifestStoreLabel, {manifest_box});

  // 5. Call ConvertManifestStoreToCrJsonWithoutValidationResults.
  absl::StatusOr<nlohmann::json> j =
      ConvertToCrJsonWithoutValidationResults(manifest_store_box);
  ASSERT_THAT(j, IsOk());

  // 6. Verify that the output JSON contains the error message.
  ASSERT_TRUE(j->contains("manifests"));
  ASSERT_GT((*j)["manifests"].size(), 0);
  const auto& manifest = (*j)["manifests"][0];
  ASSERT_TRUE(manifest.contains("assertions"));
  const auto& assertions = manifest["assertions"];
  // The error should be at the top level of the "assertions" object because
  // the structure is invalid before even getting to a specific assertion label.
  ASSERT_TRUE(assertions.contains("_error"));
  EXPECT_EQ(assertions["_error"],
            "Assertion store contains non-SuperBox content");
}

TEST(ConvertManifestStoreToCrJsonTest, ClaimV2IsConverted) {
  // 1. Construct claim_generator_info map.
  cppbor::Map generator_info;
  generator_info.add("name", "Test Generator");
  generator_info.add("version", "1.0");

  // 2. Construct created_assertions array.
  cppbor::Array created_assertions;
  cppbor::Map assertion_link;
  assertion_link.add("url", "self#jumbf=/c2pa/assertions/custom.assertion");
  created_assertions.add(std::move(assertion_link));

  // 3. Construct the claim map.
  cppbor::Map claim_map;
  claim_map.add("instanceID", "test_instance_id");
  claim_map.add("claim_generator_info", std::move(generator_info));
  claim_map.add("signature", "self#jumbf=/c2pa/signature");
  claim_map.add("created_assertions", std::move(created_assertions));
  claim_map.add("dc:title", "Test Title");

  std::vector<uint8_t> encoded_claim = claim_map.encode();
  absl::string_view claim_view(
      reinterpret_cast<const char*>(encoded_claim.data()),
      encoded_claim.size());

  // 4. Wrap in CborBox.
  std::string cbor_box = jumbf::EncodeCborBox(claim_view);

  // 5. Wrap in Claim V2 SuperBox.
  std::string claim_box = jumbf::EncodeSuperBox(jumbf::kCborBoxTypeUuid,
                                                "c2pa.claim.v2", {cbor_box});

  // 6. Wrap in manifest SuperBox.
  std::string manifest_box = jumbf::EncodeSuperBox(
      kStandardManifestUuid, "test_manifest", {claim_box});

  // 7. Wrap in manifest store SuperBox.
  std::string manifest_store_box = jumbf::EncodeSuperBox(
      kManifestStoreUuid, kManifestStoreLabel, {manifest_box});

  // 8. Call ConvertManifestStoreToCrJsonWithoutValidationResults.
  absl::StatusOr<nlohmann::json> j =
      ConvertToCrJsonWithoutValidationResults(manifest_store_box);
  ASSERT_THAT(j, IsOk());

  // 9. Verify claim.v2 fields in output JSON.
  ASSERT_TRUE(j->contains("manifests"));
  ASSERT_GT((*j)["manifests"].size(), 0);
  const auto& manifest = (*j)["manifests"][0];
  ASSERT_TRUE(manifest.contains("claim.v2"));
  const auto& claim_json = manifest["claim.v2"];

  EXPECT_EQ(claim_json["instanceID"], "test_instance_id");
  EXPECT_EQ(claim_json["dc:title"], "Test Title");
  EXPECT_EQ(claim_json["signature"], "self#jumbf=/c2pa/signature");

  ASSERT_TRUE(claim_json.contains("claim_generator_info"));
  EXPECT_EQ(claim_json["claim_generator_info"]["name"], "Test Generator");
  EXPECT_EQ(claim_json["claim_generator_info"]["version"], "1.0");

  ASSERT_TRUE(claim_json.contains("created_assertions"));
  ASSERT_GT(claim_json["created_assertions"].size(), 0);
  EXPECT_EQ(claim_json["created_assertions"][0]["url"],
            "self#jumbf=/c2pa/assertions/custom.assertion");
}

TEST(ConvertManifestStoreToCrJsonTest, ClaimV2WithMetadataIsConverted) {
  // 1. Construct claim_generator_info map.
  cppbor::Map generator_info;
  generator_info.add("name", "Test Generator");
  generator_info.add("version", "1.0");

  // 2. Construct created_assertions array.
  cppbor::Array created_assertions;
  cppbor::Map assertion_link;
  assertion_link.add("url", "self#jumbf=/c2pa/assertions/custom.assertion");
  created_assertions.add(std::move(assertion_link));

  // 3. Construct metadata map.
  cppbor::Map metadata_map;
  metadata_map.add("dateTime", "2023-05-21T00:00:00Z");

  // rating
  cppbor::Array rating_array;
  cppbor::Map rating_map;
  rating_map.add("value", "suitable-for-all");
  rating_map.add("code", "G");
  rating_map.add("explanation", "General Audiences");
  rating_array.add(std::move(rating_map));
  metadata_map.add("rating", std::move(rating_array));

  // dataSource
  cppbor::Map datasource_map;
  datasource_map.add("type", "camera");
  datasource_map.add("details", "Captured by hardware");
  metadata_map.add("dataSource", std::move(datasource_map));

  // reference
  cppbor::Map reference_map;
  reference_map.add("url", "self#jumbf=/c2pa/assertions/custom.assertion");
  metadata_map.add("reference", std::move(reference_map));

  // localizations
  cppbor::Array localizations_array;
  cppbor::Map localization_map;
  localization_map.add("en", "English");
  localizations_array.add(std::move(localization_map));
  metadata_map.add("localizations", std::move(localizations_array));

  // regionOfInterest
  cppbor::Map region_map;
  region_map.add("foo", "bar");
  metadata_map.add("regionOfInterest", std::move(region_map));

  // 4. Construct the claim map.
  cppbor::Map claim_map;
  claim_map.add("instanceID", "test_instance_id");
  claim_map.add("claim_generator_info", std::move(generator_info));
  claim_map.add("signature", "self#jumbf=/c2pa/signature");
  claim_map.add("created_assertions", std::move(created_assertions));
  claim_map.add("dc:title", "Test Title");
  claim_map.add("metadata", std::move(metadata_map));

  std::vector<uint8_t> encoded_claim = claim_map.encode();
  absl::string_view claim_view(
      reinterpret_cast<const char*>(encoded_claim.data()),
      encoded_claim.size());

  // 5. Wrap in CborBox.
  std::string cbor_box = jumbf::EncodeCborBox(claim_view);

  // 6. Wrap in Claim V2 SuperBox.
  std::string claim_box = jumbf::EncodeSuperBox(jumbf::kCborBoxTypeUuid,
                                                "c2pa.claim.v2", {cbor_box});

  // 7. Wrap in manifest SuperBox.
  std::string manifest_box = jumbf::EncodeSuperBox(
      kStandardManifestUuid, "test_manifest", {claim_box});

  // 8. Wrap in manifest store SuperBox.
  std::string manifest_store_box = jumbf::EncodeSuperBox(
      kManifestStoreUuid, kManifestStoreLabel, {manifest_box});

  // 9. Call ConvertManifestStoreToCrJsonWithoutValidationResults.
  absl::StatusOr<nlohmann::json> j =
      ConvertToCrJsonWithoutValidationResults(manifest_store_box);
  ASSERT_THAT(j, IsOk());

  // 10. Verify metadata fields in output JSON.
  ASSERT_TRUE(j->contains("manifests"));
  ASSERT_GT((*j)["manifests"].size(), 0);
  const auto& manifest = (*j)["manifests"][0];
  ASSERT_TRUE(manifest.contains("claim.v2"));
  const auto& claim_json = manifest["claim.v2"];

  ASSERT_TRUE(claim_json.contains("metadata"));
  const auto& metadata_json = claim_json["metadata"];

  EXPECT_EQ(metadata_json["dateTime"], "2023-05-21T00:00:00Z");

  ASSERT_TRUE(metadata_json.contains("rating"));
  ASSERT_GT(metadata_json["rating"].size(), 0);
  EXPECT_EQ(metadata_json["rating"][0]["value"], "suitable-for-all");
  EXPECT_EQ(metadata_json["rating"][0]["code"], "G");
  EXPECT_EQ(metadata_json["rating"][0]["explanation"], "General Audiences");

  ASSERT_TRUE(metadata_json.contains("dataSource"));
  EXPECT_EQ(metadata_json["dataSource"]["type"], "camera");
  EXPECT_EQ(metadata_json["dataSource"]["details"], "Captured by hardware");

  ASSERT_TRUE(metadata_json.contains("reference"));
  EXPECT_EQ(metadata_json["reference"]["url"],
            "self#jumbf=/c2pa/assertions/custom.assertion");

  // Localizations and RegionOfInterest are currently converted to empty objects
  // but we still verify they exist.
  ASSERT_TRUE(metadata_json.contains("localizations"));
  EXPECT_TRUE(metadata_json["localizations"].is_array());
  ASSERT_TRUE(metadata_json.contains("regionOfInterest"));
  EXPECT_TRUE(metadata_json["regionOfInterest"].is_object());
}

}  // namespace
}  // namespace credentio
