// 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 <cstddef>
#include <cstdint>
#include <memory>
#include <optional>
#include <string>
#include <utility>
#include <vector>

#include "absl/base/nullability.h"
#include "absl/container/flat_hash_map.h"
#include "absl/status/status.h"
#include "absl/status/status_macros.h"
#include "absl/status/statusor.h"
#include "absl/strings/match.h"
#include "absl/strings/numbers.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "absl/time/clock.h"
#include "absl/time/time.h"
#include "cbor/cbor.h"
#include "cbor/parse.h"
#include "constants/labels.h"
#include "cose/sig_structure.h"
#include "cose/simple_cms_parser.h"
#include "crypto/algorithms.h"
#include "google/protobuf/repeated_ptr_field.h"
#include "jumbf/box.h"
#include "jumbf/convert_json.h"  // IWYU pragma: keep
#include "jumbf/parse.h"
#include "nlohmann/json.hpp"
#include "nlohmann/json_fwd.hpp"
#include "openssl/asn1.h"
#include "openssl/bn.h"
#include "openssl/mem.h"
#include "openssl/obj.h"
#include "openssl/x509.h"
#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"
#include "tsp/timestamp_verifier.h"
#include "utils/crjson_utils.h"
#include "validator/result.h"

namespace credentio {

namespace {

using Json = ::nlohmann::json;

// =============================================================================
// JUMBF/CBOR Helpers
// =============================================================================

template <typename T>
absl::StatusOr<const T&> EnsureAndGetSingleBox(const jumbf::SuperBox& box) {
  if (box.contents.size() != 1) {
    return absl::InvalidArgumentError(
        absl::StrCat(box.description.label.value_or("unspecified"),
                     " box must contain exactly one box"));
  }
  if (!box.contents[0].Holds<T>()) {
    return absl::InvalidArgumentError(absl::StrCat(
        box.description.label.value_or("unspecified"),
        " must contained box of index: ", box.contents[0].payload.index()));
  }
  return box.contents[0].Get<T>();
}

template <typename T>
struct ParsedCbor {
  std::unique_ptr<cbor::ParseResult> parse_result;
  T cbor_view;
};

absl::StatusOr<ParsedCbor<cbor::MapView>> ParseCborMap(absl::string_view cbor) {
  ABSL_ASSIGN_OR_RETURN(std::unique_ptr<cbor::ParseResult> parse_result,
                        cbor::Parse(cbor));
  ABSL_ASSIGN_OR_RETURN(cbor::MapView cbor_map, parse_result->AsMap());
  return ParsedCbor<cbor::MapView>{std::move(parse_result), cbor_map};
}

absl::StatusOr<ParsedCbor<cbor::MapView>> GetCborMap(
    const jumbf::SuperBox& box) {
  ABSL_ASSIGN_OR_RETURN(const jumbf::CborBox& cbor_box,
                        EnsureAndGetSingleBox<jumbf::CborBox>(box));
  return ParseCborMap(cbor_box.payload);
}

enum class ManifestType {
  kUnknown,
  kStandard,
  kUpdate,
  kCompressed,
  kTimestamp,
};

ManifestType GetManifestType(const jumbf::SuperBox& superbox) {
  const auto& uuid = superbox.description.type_uuid;
  if (uuid == kStandardManifestUuid) {
    return ManifestType::kStandard;
  }
  if (uuid == kUpdateManifestUuid) {
    return ManifestType::kUpdate;
  }
  if (uuid == kCompressedManifestUuid) {
    return ManifestType::kCompressed;
  }
  if (uuid == kTimestampManifestUuid) {
    return ManifestType::kTimestamp;
  }
  return ManifestType::kUnknown;
}

// =============================================================================
// Generic Array Converters
// =============================================================================

Json ConvertArrayOfStrings(uint32_t _, const cbor::ItemView& item) {
  auto val = item.GetString();
  if (!val.ok()) {
    return Json({{"_error", val.status().message()}});
  }
  return Json(*val);
}

// =============================================================================
// Assertion Converters
// =============================================================================

Json ConvertThumbnailAssertion(const jumbf::SuperBox& box) {
  Json crjson = Json::object();
  absl::string_view label = box.description.label.value_or("");

  if (absl::StartsWith(label, "c2pa.thumbnail.claim")) {
    crjson["thumbnailType"] = 0;
  } else if (absl::StartsWith(label, "c2pa.thumbnail.ingredient")) {
    crjson["thumbnailType"] = 1;
  }

  size_t prefix_len = absl::StartsWith(label, "c2pa.thumbnail.claim") ? 20 : 25;
  size_t last_dot = label.rfind('.');
  if (last_dot != absl::string_view::npos && last_dot >= prefix_len) {
    absl::string_view mime_type = label.substr(last_dot + 1);
    size_t suffix_start = mime_type.find("__");
    if (suffix_start != absl::string_view::npos) {
      mime_type = mime_type.substr(0, suffix_start);
    }
    crjson["mimeType"] = std::string(mime_type);
  }

  return crjson;
}

Json ConvertMetadataAssertion(const jumbf::SuperBox& box) {
  Json crjson = Json::object();

  auto json_box = EnsureAndGetSingleBox<jumbf::JsonBox>(box);
  if (json_box.ok()) {
    Json j;
    jumbf::to_json(j, *json_box);
    if (j.contains("json")) {
      return j["json"];
    } else {
      crjson["_error"] = "Failed to convert JSON box to JSON";
      return crjson;
    }
  } else {
    crjson["_error"] = "Metadata assertion is not a JSON box";
    return crjson;
  }
}

bool LabelMatches(absl::string_view label, absl::string_view base_label) {
  if (!absl::StartsWith(label, base_label)) {
    return false;
  }
  if (label.size() == base_label.size()) {
    return true;
  }
  if (label.size() > base_label.size() + 2 &&
      label.substr(base_label.size(), 2) == "__") {
    absl::string_view number = label.substr(base_label.size() + 2);
    uint64_t val;
    return absl::SimpleAtoi(number, &val);
  }
  return false;
}

// This is an allowlist of standard assertions that are supported by C2PA v2.4.
bool IsAllowlistedStandardAssertion(absl::string_view label) {
  return LabelMatches(label, kDataHashAssertionLabel) ||
         LabelMatches(label, kDataHashAssertionPartLabel) ||
         LabelMatches(label, kBmffBasedHashAssertionV2Label) ||
         LabelMatches(label, kBmffBasedHashAssertionV3Label) ||
         LabelMatches(label, kBmffBasedHashAssertionV2PartLabel) ||
         LabelMatches(label, kBmffBasedHashAssertionV3PartLabel) ||
         LabelMatches(label, kBoxesHashAssertionLabel) ||
         LabelMatches(label, kBoxesHashAssertionPartLabel) ||
         LabelMatches(label, kMultiAssetHashAssertionLabel) ||
         LabelMatches(label, kCollectionDataHashAssertionLabel) ||
         LabelMatches(label, kSoftBindingAssertionLabel) ||
         LabelMatches(label, kActionsAssertionV1Label) ||
         LabelMatches(label, kActionsAssertionV2Label) ||
         LabelMatches(label, kIngredientAssertionV1Label) ||
         LabelMatches(label, kIngredientAssertionV2Label) ||
         LabelMatches(label, kIngredientAssertionV3Label) ||
         LabelMatches(label, "font.info") ||
         LabelMatches(label, "c2pa.font.info") ||
         LabelMatches(label, "c2pa.cloud-data") ||
         LabelMatches(label, "c2pa.session-keys") ||
         LabelMatches(label, "c2pa.ai-disclosure") ||
         LabelMatches(label, "c2pa.certificate-status") ||
         LabelMatches(label, "c2pa.asset-ref") ||
         LabelMatches(label, "c2pa.depthmap") ||
         LabelMatches(label, "c2pa.repository-receipt") ||
         LabelMatches(label, "c2pa.embedded_data") ||
         LabelMatches(label, "c2pa.environmental-sustainability") ||
         LabelMatches(label, "c2pa.time-stamp");
}

Json ConvertAssertionStore(const jumbf::SuperBox& box) {
  Json crjson = Json::object();

  for (const jumbf::ContentBox& content_box : box.contents) {
    if (!content_box.Holds<jumbf::SuperBox>()) {
      crjson["_error"] = "Assertion store contains non-SuperBox content";
      continue;
    }

    const jumbf::SuperBox& child_box = content_box.Get<jumbf::SuperBox>();
    absl::string_view label = child_box.description.label.value_or("");
    if (absl::StartsWith(label, "c2pa.thumbnail.claim") ||
        absl::StartsWith(label, "c2pa.thumbnail.ingredient")) {
      crjson[label] = ConvertThumbnailAssertion(child_box);
    } else if (LabelMatches(label, "c2pa.metadata")) {
      crjson[label] = ConvertMetadataAssertion(child_box);
    } else if (IsAllowlistedStandardAssertion(label)) {
      if (auto cbor_box = EnsureAndGetSingleBox<jumbf::CborBox>(child_box);
          cbor_box.ok()) {
        Json j;
        jumbf::to_json(j, *cbor_box);
        if (j.contains("cbor")) {
          crjson[label] = j["cbor"];
        } else {
          crjson[label] = Json::object();
          crjson[label]["_error"] = "Failed to convert CBOR to JSON";
        }
      } else if (auto json_box =
                     EnsureAndGetSingleBox<jumbf::JsonBox>(child_box);
                 json_box.ok()) {
        Json j;
        jumbf::to_json(j, *json_box);
        if (j.contains("json")) {
          crjson[label] = j["json"];
        } else {
          crjson[label] = Json::object();
          crjson[label]["_error"] = "Failed to convert JSON box to JSON";
        }
      }
    } else {
      crjson[label] = Json::object();
    }
  }

  return crjson;
}

// =============================================================================
// Claim Helpers
// =============================================================================

// Converts a hashed URI map to a crJSON object.
//  - CBOR CDDL:
//  https://spec.c2pa.org/specifications/specifications/2.4/specs/C2PA_Specification.html#_embedded
Json ConvertHashedUri(const cbor::MapView& uri_map) {
  Json crjson = Json::object();
  RecordString(uri_map, "url", true, crjson);
  RecordString(uri_map, "alg", false, crjson);
  RecordByteString(uri_map, "hash", true, crjson);
  return crjson;
}

Json ConvertClaimGeneratorInfo(const cbor::MapView& map) {
  Json crjson = Json::object();
  RecordString(map, "name", true, crjson);
  RecordString(map, "version", false, crjson);
  RecordMap(map, "icon", false, ConvertHashedUri, crjson);
  RecordString(map, "operating_system", false, crjson);
  return crjson;
}

Json ConvertRating(const cbor::MapView& map) {
  Json rating = Json::object();
  RecordString(map, "value", true, rating);
  RecordString(map, "code", false, rating);
  RecordString(map, "explanation", false, rating);
  return rating;
}

Json ConvertSourceMap(const cbor::MapView& map) {
  Json crjson = Json::object();
  RecordString(map, "type", true, crjson);
  RecordString(map, "details", false, crjson);
  return crjson;
}

Json ConvertLocalizations(const cbor::MapView& map) {
  Json crjson = Json::object();
  // Dynamic fields...
  return crjson;
}

Json ConvertRegionOfInterest(const cbor::MapView& map) {
  Json crjson = Json::object();
  // No fields in the spec.
  return crjson;
}

Json ConvertMetadata(const cbor::MapView& map) {
  Json crjson = Json::object();
  RecordString(map, "dateTime", false, crjson);
  RecordArrayOfMaps(map, "rating", false, ConvertRating, crjson);
  RecordMap(map, "reference", false, ConvertHashedUri, crjson);
  RecordMap(map, "dataSource", false, ConvertSourceMap, crjson);
  RecordArrayOfMaps(map, "localizations", false, ConvertLocalizations, crjson);
  RecordMap(map, "regionOfInterest", false, ConvertRegionOfInterest, crjson);
  return crjson;
}

// =============================================================================
// Claim Converters
// =============================================================================

Json ConvertClaimV2(const jumbf::SuperBox& box) {
  Json crjson = Json::object();

  auto parsed_cbor = GetCborMap(box);
  if (!parsed_cbor.ok()) {
    crjson["_error"] = parsed_cbor.status().message();
    return crjson;
  }

  RecordString(parsed_cbor->cbor_view, "instanceID", true, crjson);
  RecordMap(parsed_cbor->cbor_view, "claim_generator_info", true,
            ConvertClaimGeneratorInfo, crjson);
  RecordString(parsed_cbor->cbor_view, "signature", true, crjson);
  RecordArrayOfMaps(parsed_cbor->cbor_view, "created_assertions", true,
                    ConvertHashedUri, crjson);
  RecordArrayOfMaps(parsed_cbor->cbor_view, "gathered_assertions", true,
                    ConvertHashedUri, crjson);
  RecordString(parsed_cbor->cbor_view, "dc:title", false, crjson);
  RecordArray(parsed_cbor->cbor_view, "redacted_assertions", true,
              ConvertArrayOfStrings, crjson);
  RecordString(parsed_cbor->cbor_view, "alg", false, crjson);
  RecordString(parsed_cbor->cbor_view, "alg_soft", false, crjson);
  RecordString(parsed_cbor->cbor_view, "specVersion", false, crjson);
  RecordMap(parsed_cbor->cbor_view, "metadata", false, ConvertMetadata, crjson);

  return crjson;
}

// =============================================================================
// Signature Helpers
// =============================================================================

Json ConvertDNParsed(X509_NAME* name) {
  Json dn_map = Json::object();
  if (!name) return dn_map;
  int count = X509_NAME_entry_count(name);
  for (int i = 0; i < count; ++i) {
    X509_NAME_ENTRY* entry = X509_NAME_get_entry(name, i);
    ASN1_OBJECT* obj = X509_NAME_ENTRY_get_object(entry);
    ASN1_STRING* str = X509_NAME_ENTRY_get_data(entry);

    int nid = OBJ_obj2nid(obj);
    const char* short_name = OBJ_nid2sn(nid);

    unsigned char* utf8_str = nullptr;
    int len = ASN1_STRING_to_UTF8(&utf8_str, str);
    if (len >= 0) {
      if (short_name) {
        dn_map[short_name] =
            std::string(reinterpret_cast<char*>(utf8_str), len);
      } else {
        char oid_buf[128];
        OBJ_obj2txt(oid_buf, sizeof(oid_buf), obj, 1);
        dn_map[oid_buf] = std::string(reinterpret_cast<char*>(utf8_str), len);
      }
      OPENSSL_free(utf8_str);
    }
  }
  return dn_map;
}

std::string ConvertASN1TimeToISO8601(const ASN1_TIME* t) {
  if (!t) return "";

  int64_t posix_time;
  if (ASN1_TIME_to_posix(t, &posix_time) == 0) {
    return "";
  }
  return absl::FormatTime(absl::RFC3339_full, absl::FromUnixSeconds(posix_time),
                          absl::UTCTimeZone());
}

Json ConvertCertificateInfo(absl::string_view certificate_der) {
  Json cert_info = Json::object();

  const uint8_t* p = reinterpret_cast<const uint8_t*>(certificate_der.data());
  X509* cert = d2i_X509(nullptr, &p, certificate_der.size());
  if (!cert) {
    cert_info["_error"] = "Failed to parse certificate";
    return cert_info;
  }

  ASN1_INTEGER* serial = X509_get_serialNumber(cert);
  BIGNUM* bn = ASN1_INTEGER_to_BN(serial, nullptr);
  if (bn) {
    char* hex = BN_bn2hex(bn);
    if (hex) {
      cert_info["serialNumber"] = std::string(hex);
      OPENSSL_free(hex);
    }
    BN_free(bn);
  }

  cert_info["subject"] = ConvertDNParsed(X509_get_subject_name(cert));
  cert_info["issuer"] = ConvertDNParsed(X509_get_issuer_name(cert));

  Json validity = Json::object();
  validity["notBefore"] = ConvertASN1TimeToISO8601(X509_get0_notBefore(cert));
  validity["notAfter"] = ConvertASN1TimeToISO8601(X509_get0_notAfter(cert));
  cert_info["validity"] = validity;

  X509_free(cert);
  return cert_info;
}

// =============================================================================
// Signature Converter
// =============================================================================

Json ConvertClaimSignature(const jumbf::SuperBox& box) {
  Json crjson = Json::object();

  auto cbor_box = EnsureAndGetSingleBox<jumbf::CborBox>(box);
  if (!cbor_box.ok()) {
    return crjson;
  }

  auto cose_sign1 = DecodeCoseSign1TaggedStructure(cbor_box->payload);
  if (!cose_sign1.ok()) {
    return crjson;
  }

  auto protected_header = DecodeProtectedHeader(cose_sign1->protected_header);
  if (protected_header.ok()) {
    crjson["algorithm"] = absl::StrCat(protected_header->alg);
  }

  std::vector<std::string> cert_chain;
  if (!cose_sign1->unprotected_header.certificate_chain.empty()) {
    cert_chain = cose_sign1->unprotected_header.certificate_chain;
  } else if (protected_header.ok()) {
    cert_chain = protected_header->certificate_chain;
  }

  if (!cert_chain.empty()) {
    crjson["certificateInfo"] = ConvertCertificateInfo(cert_chain[0]);
  }

  // Handle Timestamp
  auto timestamp_container = cose_sign1->unprotected_header.sig_tst2;
  if (!timestamp_container.has_value()) {
    timestamp_container = cose_sign1->unprotected_header.sig_tst;
  }

  if (timestamp_container.has_value() &&
      !timestamp_container->tst_tokens.empty()) {
    if (timestamp_container->tst_tokens.size() == 1) {
      absl::string_view timestamp_token =
          timestamp_container->tst_tokens[0].val;
      TimestampVerifier verifier(nullptr);  // Skip trust checks
      auto parsed_token = SimpleParsedTimestampToken::Create(timestamp_token);
      if (parsed_token.ok()) {
        auto verified_timestamp = verifier.VerifyTimestampToken(**parsed_token);
        if (verified_timestamp.ok()) {
          Json ts_info = Json::object();
          ts_info["timestamp"] = absl::FormatTime(
              absl::RFC3339_full, verified_timestamp->asserted_time(),
              absl::UTCTimeZone());
          ts_info["certificateInfo"] =
              ConvertCertificateInfo(verified_timestamp->tsa_certificate());
          crjson["timeStampInfo"] = ts_info;
        }
      }
    }
  }

  return crjson;
}

Json ConvertValidationStatusSetToJson(
    const ValidationStatusSet& validation,
    std::optional<absl::string_view> spec_version = std::nullopt,
    std::optional<absl::string_view> trust_list_uri = std::nullopt) {
  Json v = Json::object();
  v["success"] = Json::array();
  v["informational"] = Json::array();
  v["failure"] = Json::array();
  if (spec_version.has_value()) {
    v["specVersion"] = *spec_version;
  }
  if (trust_list_uri.has_value()) {
    v["trustListURI"] = *trust_list_uri;
  }
  v["validationTime"] =
      absl::FormatTime(absl::RFC3339_full, absl::Now(), absl::UTCTimeZone());

  for (const auto& success : validation.successes()) {
    Json s = Json::object();
    s["code"] = success.code();
    if (!success.url().empty()) {
      s["url"] = success.url();
    }
    if (!success.explanation().empty()) {
      s["explanation"] = success.explanation();
    }
    v["success"].push_back(s);
  }
  for (const auto& informational : validation.informationals()) {
    Json i = Json::object();
    i["code"] = informational.code();
    if (!informational.url().empty()) {
      i["url"] = informational.url();
    }
    if (!informational.explanation().empty()) {
      i["explanation"] = informational.explanation();
    }
    v["informational"].push_back(i);
  }
  for (const auto& failure : validation.failures()) {
    Json f = Json::object();
    f["code"] = failure.code();
    if (!failure.url().empty()) {
      f["url"] = failure.url();
    }
    if (!failure.explanation().empty()) {
      f["explanation"] = failure.explanation();
    }
    v["failure"].push_back(f);
  }
  return v;
}

// =============================================================================
// Top-Level Converters
// =============================================================================

Json ConvertManifestToCrJson(
    const jumbf::SuperBox& manifest_box,
    const ValidationStatusSet* validation_status = nullptr,
    const google::protobuf::RepeatedPtrField<IngredientDeltaValidationResult>*
        ingredient_deltas = nullptr,
    std::optional<absl::string_view> spec_version = std::nullopt,
    std::optional<absl::string_view> trust_list_uri = std::nullopt) {
  Json crjson = Json::object();
  crjson["label"] = manifest_box.description.label.value_or("");
  switch (GetManifestType(manifest_box)) {
    case ManifestType::kStandard:
      crjson["isUpdateManifest"] = false;
      crjson["isCompressedManifest"] = false;
      break;
    case ManifestType::kUpdate:
      crjson["isUpdateManifest"] = true;
      crjson["isCompressedManifest"] = false;
      break;
    case ManifestType::kCompressed:
      crjson["isCompressedManifest"] = true;
      crjson["_error"] = "Compressed manifests are not supported";
      // Compressed manifest are not supported, so mark an error and return.
      return crjson;
    default:
      crjson["_error"] = "Unknown manifest type";
      // Unknown manifest type, so mark an error and return.
      return crjson;
  }
  crjson["assertions"] = Json::object();
  crjson["signature"] = Json::object();

  if (validation_status != nullptr) {
    crjson["validationResults"] = ConvertValidationStatusSetToJson(
        *validation_status, spec_version, trust_list_uri);
  } else {
    crjson["validationResults"] = Json::object();
    crjson["validationResults"]["success"] = Json::array();
    crjson["validationResults"]["informational"] = Json::array();
    crjson["validationResults"]["failure"] = Json::array();
    if (spec_version.has_value()) {
      crjson["validationResults"]["specVersion"] = *spec_version;
    }
    if (trust_list_uri.has_value()) {
      crjson["validationResults"]["trustListURI"] = *trust_list_uri;
    }
    crjson["validationResults"]["validationTime"] =
        absl::FormatTime(absl::RFC3339_full, absl::Now(), absl::UTCTimeZone());
  }

  if (ingredient_deltas != nullptr && !ingredient_deltas->empty()) {
    crjson["ingredientDeltas"] = Json::array();
    for (const auto& delta : *ingredient_deltas) {
      Json d = Json::object();
      d["ingredientAssertionURI"] = delta.ingredient_assertion_uri();
      // Ingredient deltas should not have spec version or trust list URI.
      d["validationDeltas"] =
          ConvertValidationStatusSetToJson(delta.validation_deltas());
      crjson["ingredientDeltas"].push_back(d);
    }
  }

  for (const jumbf::ContentBox& content_box : manifest_box.contents) {
    if (!content_box.Holds<jumbf::SuperBox>()) {
      crjson["_error"] = "Manifest contains non-SuperBox content";
      continue;
    }

    const jumbf::SuperBox& child_box = content_box.Get<jumbf::SuperBox>();
    if (child_box.description.label.value_or("") == kAssertionStoreLabel) {
      crjson["assertions"] = ConvertAssertionStore(child_box);
    } else if (child_box.description.label.value_or("") == kClaimV2Label) {
      crjson["claim.v2"] = ConvertClaimV2(child_box);
    } else if (child_box.description.label.value_or("") ==
               kClaimSignatureLabel) {
      crjson["signature"] = ConvertClaimSignature(child_box);
    } else if (child_box.description.label.value_or("") == "c2pa.databoxes") {
      // Deprecated, ignore it.
    } else {
      // Ignore unhandled top-level boxes in manifest.
    }
  }

  return crjson;
}

absl::flat_hash_map<std::string, ValidationStatusSet> IndexResults(
    const ValidationResultProto* absl_nullable validation_result) {
  absl::flat_hash_map<std::string, ValidationStatusSet> manifests;
  if (validation_result != nullptr) {
    if (validation_result->has_active_manifest()) {
      manifests[validation_result->active_manifest().label()] =
          validation_result->active_manifest().validation();
    }
    for (const auto& ingredient : validation_result->ingredient_manifests()) {
      manifests[ingredient.label()] = ingredient.validation();
    }
  }
  return manifests;
}

absl::StatusOr<Json> ConvertManifestStoreToCrJsonInternal(
    absl::string_view raw_manifest_store,
    const ValidationResultProto* absl_nullable validation_result,
    const IngredientValidationResultProto* absl_nullable
        ingredient_validation_result) {
  auto indexed_validation_results = IndexResults(validation_result);

  // Get the spec version and trust list URI from the validation results.
  std::optional<absl::string_view> spec_version;
  std::optional<absl::string_view> trust_list_uri;
  if (validation_result != nullptr) {
    if (validation_result->has_spec_version()) {
      spec_version = validation_result->spec_version();
    }
    if (validation_result->has_trust_list_uri()) {
      trust_list_uri = validation_result->trust_list_uri();
    }
  } else if (ingredient_validation_result != nullptr) {
    if (ingredient_validation_result->has_ingredient_validation_results()) {
      if (ingredient_validation_result->ingredient_validation_results()
              .has_spec_version()) {
        spec_version =
            ingredient_validation_result->ingredient_validation_results()
                .spec_version();
      }
      if (ingredient_validation_result->ingredient_validation_results()
              .has_trust_list_uri()) {
        trust_list_uri =
            ingredient_validation_result->ingredient_validation_results()
                .trust_list_uri();
      }
    }
  }

  ABSL_ASSIGN_OR_RETURN(
      jumbf::SuperBox manifest_store_box,
      jumbf::ConsumeSuperBox(&raw_manifest_store, /*recursion_limit=*/-1));

  // Build the crJSON.
  Json crjson = Json::object();

  // Add the context.
  crjson["@context"] =
      Json::array({"https://c2pa.org/crjson/crJSON.schema.json"});

  // Add the manifests.
  crjson["manifests"] = Json::array();
  bool is_active_manifest = true;
  for (auto it = manifest_store_box.contents.rbegin();
       it != manifest_store_box.contents.rend(); ++it) {
    const jumbf::ContentBox& content_box = *it;
    if (!content_box.Holds<jumbf::SuperBox>()) {
      crjson["_error"] = "Manifest store contains non-SuperBox content";
      continue;
    }

    auto manifest_box = content_box.Get<jumbf::SuperBox>();
    auto results = indexed_validation_results.find(
        manifest_box.description.label.value_or(""));

    const ValidationStatusSet* validation_status = nullptr;
    if (results != indexed_validation_results.end()) {
      validation_status = &results->second;
    } else if (is_active_manifest && ingredient_validation_result != nullptr &&
               ingredient_validation_result
                   ->has_ingredient_validation_results()) {
      validation_status =
          &ingredient_validation_result->ingredient_validation_results()
               .active_manifest();
    }

    crjson["manifests"].push_back(ConvertManifestToCrJson(
        manifest_box, validation_status,
        /*ingredient_deltas=*/nullptr, spec_version, trust_list_uri));

    is_active_manifest = false;  // Only first one is active
  }

  // JSON generator info.
  crjson["jsonGenerator"]["name"] = "Google C2PA Toolkit";
  crjson["jsonGenerator"]["version"] = "0.0.1";

  return crjson;
}

}  // namespace

absl::StatusOr<Json> ConvertToCrJsonWithoutValidationResults(
    absl::string_view raw_manifest_store) {
  return ConvertManifestStoreToCrJsonInternal(raw_manifest_store, nullptr,
                                              nullptr);
}

absl::StatusOr<Json> ConvertToCrJson(
    const ValidationResult& validation_result) {
  return ConvertManifestStoreToCrJsonInternal(
      validation_result.manifest_store_bytes(), &validation_result.proto(),
      nullptr);
}

absl::StatusOr<Json> ConvertToCrJson(
    const IngredientValidationResultProto& ingredient_validation_result) {
  return ConvertManifestStoreToCrJsonInternal(
      ingredient_validation_result.manifest_store_bytes(), nullptr,
      &ingredient_validation_result);
}

}  // namespace credentio
