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

edition = "2024";

package credentio;

import "proto/assertion.proto";
import "proto/bmff_based_hash_assertion.proto";
import "proto/boxes_hash_assertion.proto";
import "proto/collection_data_hash_assertion.proto";
import "proto/data_hash_assertion.proto";
import "proto/generator_info.proto";
import "proto/ingredient_assertion.proto";
import "proto/signature_info.proto";

import option "google/protobuf/cpp_features.proto";

option features.(pb.cpp).string_type = STRING;
option java_outer_classname = "IngredientValidationResult";
option objc_class_prefix = "C2PA";

// Result of a successful or failed validation of an ingredient asset.
message IngredientValidationResultProto {
  // Optional.
  // If omitted, the ingredient will be treated as having unknown provenance and
  // ingredient_validation_results will be ignored.
  bytes manifest_store_bytes = 1;

  // The IANA media type of the asset (e.g. "image/jpeg"), if known.
  string media_type = 6;

  // Optional. Full validation results for the ingredient.
  // SHOULD BE SET IF `manifest_store_bytes` IS SET.
  IngredientValidationResults ingredient_validation_results = 2;

  // Metadata about the ingredient asset for logging/monitoring purposes.
  IngredientValidationLoggingMetadata logging_metadata = 3;

  // Optional. Metadata about the ingredient asset for legacy manifests.
  LegacyIngredientMetadata legacy_ingredient_metadata = 5;

  // Contains the URI and redaction reason for a redacted assertion.
  message RedactedAssertion {
    string uri = 1;
    string reason = 2;
  }

  // DO NOT MANUALLY SET. If set then `manifest_store_bytes` contains the
  // redacted ingredient manifest store. Should only be set by the
  // ManifestStoreRedactor.
  repeated RedactedAssertion redactions = 7;

  // Optional. The summarized digital source type of the ingredient asset, if
  // known. Used in cases of unknown provenance or if the ingredient manifest
  // store was redacted.
  string digital_source_type = 8;

  reserved 4;
}

// Result of a partial validation of an ingredient manifest store, where the
// content binding has not yet been validated.
message PartialIngredientValidationResultProto {
  // Required. Validation results for the ingredient not including hard binding
  // validation results.
  IngredientValidationResults ingredient_validation_results = 1;

  // Metadata about the ingredient asset for logging/monitoring purposes.
  IngredientValidationLoggingMetadata logging_metadata = 3;

  // Contains the relevant hard binding assertion binding the c2pa manifest
  // store to the asset.
  message HardBindingAssertion {
    // Required.
    string hard_binding_uri = 1;
    // JUMBF URI of the relevant multi-asset hash assertion, if one was found.
    // This must be located in the same manifest as the `hard_binding_uri`.
    string multi_asset_hash_uri = 7;

    // Required. The relevant hard binding assertion.
    oneof hard_binding_assertion {
      BmffBasedHashAssertion bmff_based_hash = 2;
      DataHashAssertion data_hash = 3;
      BoxesHashAssertion boxes_hash = 4;
      CollectionDataHashAssertion collection_data_hash = 8;
    }

    // All hash assertions for the asset, including the primary hard binding
    // assertion as well as (if present) the multi-asset hash assertion and the
    // part hash assertions it references. Order is not significant.
    repeated Assertion assertions = 6;

    // Optional. If the active manifest is an update manifest then the
    // `hard_binding_uri` will point into a different manifest from the
    // `active_manifest_uri`.
    string active_manifest_uri = 5;
  }

  // Optional. The relevant hard binding assertion, if one was found.
  HardBindingAssertion hard_binding_assertion = 2;

  // Optional. Metadata about the ingredient asset for legacy manifests.
  LegacyIngredientMetadata legacy_ingredient_metadata = 5;

  // Optional. The summarized digital source type of the ingredient asset, if
  // known. Currently only set for assets with AI generation usage.
  string digital_source_type = 6;
}

message LegacyIngredientMetadata {
  // True if the active manifest is a legacy manifest.
  bool is_legacy_ingredient = 1;
  // Includes labels of legacy manifests unsupported by this validator.
  repeated string unsupported_manifests = 2;
  // Includes JUMBF URIs of ingredient assertions that point to legacy manifests
  // unsupported by this validator. Assertions may be in any of the ingredient
  // manifests or the active manifest.
  repeated string unsupported_ingredient_assertion_uris = 3;
}

// Metadata about an ingredient asset for logging/monitoring purposes.
message IngredientValidationLoggingMetadata {
  message ManifestInfo {
    GeneratorInfo claim_generator = 1;
    SignatureInfo signature = 2;
  }
  // Information about the active manifest.
  ManifestInfo active_manifest = 1;
}
