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

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) {
  auto parse_result = cbor::Parse(cbor);
  if (!parse_result.ok()) {
    return parse_result.status();
  }
  auto cbor_map = (*parse_result)->AsMap();
  if (!cbor_map.ok()) {
    return cbor_map.status();
  }
  return ParsedCbor<cbor::MapView>{std::move(*parse_result), *cbor_map};
}

absl::StatusOr<ParsedCbor<cbor::MapView>> GetCborMap(
    const jumbf::SuperBox& box) {
  auto cbor_box = EnsureAndGetSingleBox<jumbf::CborBox>(box);
  if (!cbor_box.ok()) {
    return cbor_box.status();
  }
  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
// =============================================================================

std::string SigningAlgorithmToString(SigningAlgorithm alg) {
  switch (alg) {
    case SigningAlgorithm::kEs256:
      return "ES256";
    case SigningAlgorithm::kEs384:
      return "ES384";
    case SigningAlgorithm::kEs512:
      return "ES512";
    case SigningAlgorithm::kPs256:
      return "PS256";
    case SigningAlgorithm::kPs384:
      return "PS384";
    case SigningAlgorithm::kPs512:
      return "PS512";
    case SigningAlgorithm::kEdDsa:
      return "Ed25519";
  }
  return "Unknown";
}

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"] = SigningAlgorithmToString(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();
      }
    }
  }

  auto manifest_store_box =
      jumbf::ConsumeSuperBox(&raw_manifest_store, /*recursion_limit=*/-1);
  if (!manifest_store_box.ok()) {
    return manifest_store_box.status();
  }

  // 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(
    absl::string_view raw_manifest_store,
    const ValidationResultProto& validation_result) {
  return ConvertManifestStoreToCrJsonInternal(raw_manifest_store,
                                              &validation_result, nullptr);
}

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

}  // namespace credentio
