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

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();
      }
    }
  }

  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
