// 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 {

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);
  ABSL_ASSERT_OK(j);

  // 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);
  ABSL_ASSERT_OK(j);

  // 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);
  ABSL_ASSERT_OK(j);

  // 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);
  ABSL_ASSERT_OK(j);

  // 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);
  ABSL_ASSERT_OK(j);

  // 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
