// 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 "validator/ingredient_result_converter.h"

#include <memory>
#include <string>
#include <utility>
#include <vector>

#include "absl/status/status.h"
#include "absl/status/status_matchers.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "proto/actions_assertion.pb.h"
#include "proto/assertion.pb.h"
#include "proto/generator_info.pb.h"
#include "proto/hashed_uri.pb.h"
#include "proto/ingredient_assertion.pb.h"
#include "proto/ingredient_validation_result.pb.h"
#include "proto/manifest.pb.h"
#include "proto/signature_info.pb.h"
#include "proto/validation_result.pb.h"
#include "proto/validation_status.pb.h"
#include "testing/proto_test_utils.h"
#include "validator/ingredient_result.h"
#include "validator/manifest_consumer.h"
#include "validator/result.h"

namespace credentio {
namespace {

using ::absl_testing::StatusIs;
using ::credentio_testing::EqualsProto;
using ::credentio_testing::ParseTextProtoOrDie;
using ::testing::ElementsAre;

TEST(IngredientResultTest, Accessors) {
  auto proto = std::make_unique<IngredientValidationResultProto>();
  proto->set_media_type("image/png");
  IngredientResult result(std::move(proto));
  EXPECT_EQ(result.proto().media_type(), "image/png");

  std::unique_ptr<IngredientValidationResultProto> released =
      std::move(result).release_proto();
  ASSERT_NE(released, nullptr);
  EXPECT_EQ(released->media_type(), "image/png");
}

TEST(IngredientResultTest, FromRvalueProto) {
  IngredientValidationResultProto proto;
  proto.set_media_type("image/png");
  IngredientResult result(std::move(proto));
  EXPECT_EQ(result.proto().media_type(), "image/png");
}

TEST(IngredientResultConverterTest, ConvertBasic) {
  ValidationResultProto input = ParseTextProtoOrDie(R"pb(
    media_type: "image/jpeg"
    active_manifest {
      label: "urn:c2pa:active"
      validation { successes { code: "success" } }
    }
  )pb");

  auto result =
      IngredientResultConverter().Convert(ValidationResult(std::move(input)));
  ABSL_ASSERT_OK(result);

  EXPECT_THAT((*result)->proto(), EqualsProto(R"pb(
                media_type: "image/jpeg"
                ingredient_validation_results {
                  active_manifest { successes { code: "success" } }
                }
                logging_metadata { active_manifest {} }
              )pb"));
}

TEST(IngredientResultConverterTest, ConvertLoggingMetadata) {
  ValidationResultProto input = ParseTextProtoOrDie(R"pb(
    active_manifest {
      label: "urn:c2pa:test"
      claim {
        claim_generator_info { name: "test_generator" }
        signature_info { issuer: "test_issuer" }
      }
    }
  )pb");

  auto result =
      IngredientResultConverter().Convert(ValidationResult(std::move(input)));
  ABSL_ASSERT_OK(result);

  EXPECT_THAT((*result)->proto(), EqualsProto(R"pb(
                logging_metadata {
                  active_manifest {
                    claim_generator { name: "test_generator" }
                    signature { issuer: "test_issuer" }
                  }
                }
              )pb"));
}

TEST(IngredientResultConverterTest, ConvertLegacyActiveManifest) {
  ValidationResultProto input = ParseTextProtoOrDie(R"pb(
    active_manifest { label: "legacy_label" }
  )pb");

  auto result =
      IngredientResultConverter().Convert(ValidationResult(std::move(input)));
  ABSL_ASSERT_OK(result);

  EXPECT_THAT((*result)->proto(), EqualsProto(R"pb(
                legacy_ingredient_metadata {
                  is_legacy_ingredient: true
                  unsupported_manifests: "legacy_label"
                }
                logging_metadata { active_manifest {} }
              )pb"));
}

TEST(IngredientResultConverterTest, ConvertIngredientDeltas) {
  ValidationResultProto input = ParseTextProtoOrDie(R"pb(
    active_manifest {
      label: "urn:c2pa:active"
      assertions {
        label: "ingredient_assertion"
        ingredient_v3 {
          active_manifest { url: "self#jumbf=/c2pa/urn:c2pa:ingredient1" }
          validation_results {
            active_manifest { successes { code: "ingredient_success" } }
          }
        }
      }
    }
    ingredient_manifests {
      label: "urn:c2pa:ingredient1"
      validation {
        successes { code: "ingredient_success" }
        failures { code: "ingredient_failure" url: "test://failure" }
      }
    }
  )pb");

  auto result =
      IngredientResultConverter().Convert(ValidationResult(std::move(input)));
  ABSL_ASSERT_OK(result);

  EXPECT_THAT(
      (*result)->proto(), EqualsProto(R"pb(
        ingredient_validation_results {
          ingredient_deltas {
            ingredient_assertion_uri: "self#jumbf=/c2pa/urn:c2pa:active/c2pa.assertions/ingredient_assertion"
            validation_deltas {
              failures { code: "ingredient_failure" url: "test://failure" }
            }
          }
        }
        logging_metadata { active_manifest {} }
      )pb"));
}

TEST(IngredientResultConverterTest, ConvertIngredientDeltasHardBinding) {
  ValidationResultProto input = ParseTextProtoOrDie(R"pb(
    active_manifest {
      label: "urn:c2pa:active"
      assertions {
        label: "ingredient_assertion"
        ingredient_v3 {
          active_manifest { url: "self#jumbf=/c2pa/urn:c2pa:ingredient1" }
          validation_results {
            active_manifest {
              successes { code: "com.google.assertion.dataHash.match" }
            }
          }
        }
      }
    }
    ingredient_manifests {
      label: "urn:c2pa:ingredient1"
      validation { successes { code: "com.google.assertion.dataHash.match" } }
    }
  )pb");

  auto result =
      IngredientResultConverter().Convert(ValidationResult(std::move(input)));
  ABSL_ASSERT_OK(result);

  EXPECT_THAT(
      (*result)->proto(), EqualsProto(R"pb(
        ingredient_validation_results {
          ingredient_deltas {
            ingredient_assertion_uri: "self#jumbf=/c2pa/urn:c2pa:active/c2pa.assertions/ingredient_assertion"
            validation_deltas {
              successes { code: "com.google.assertion.dataHash.match" url: "" }
            }
          }
        }
        logging_metadata { active_manifest {} }
      )pb"));
}

TEST(IngredientResultConverterTest, ConvertLegacyIngredientDeltas) {
  ValidationResultProto input = ParseTextProtoOrDie(R"pb(
    active_manifest {
      label: "urn:c2pa:active"
      assertions {
        label: "ingredient_assertion"
        ingredient_v3 {
          active_manifest { url: "self#jumbf=/c2pa/legacy_ingredient" }
        }
      }
    }
    ingredient_manifests { label: "legacy_ingredient" }
  )pb");

  auto result =
      IngredientResultConverter().Convert(ValidationResult(std::move(input)));
  ABSL_ASSERT_OK(result);

  EXPECT_THAT(
      (*result)->proto(), EqualsProto(R"pb(
        ingredient_validation_results {
          ingredient_deltas {
            ingredient_assertion_uri: "self#jumbf=/c2pa/urn:c2pa:active/c2pa.assertions/ingredient_assertion"
            validation_deltas {}
          }
        }
        legacy_ingredient_metadata {
          unsupported_manifests: "legacy_ingredient"
          unsupported_ingredient_assertion_uris: "self#jumbf=/c2pa/urn:c2pa:active/c2pa.assertions/ingredient_assertion"
        }
        logging_metadata { active_manifest {} }
      )pb"));
}

TEST(IngredientResultConverterTest, ConvertUnreferencedLegacyIngredient) {
  ValidationResultProto input = ParseTextProtoOrDie(R"pb(
    active_manifest { label: "urn:c2pa:active" }
    ingredient_manifests { label: "legacy_ingredient" }
  )pb");

  auto result =
      IngredientResultConverter().Convert(ValidationResult(std::move(input)));
  ABSL_ASSERT_OK(result);

  EXPECT_THAT((*result)->proto(), EqualsProto(R"pb(
                legacy_ingredient_metadata {
                  unsupported_manifests: "legacy_ingredient"
                }
                logging_metadata { active_manifest {} }
              )pb"));
}

TEST(IngredientResultConverterTest,
     ConvertActiveManifestFailuresAndInformationals) {
  ValidationResultProto input = ParseTextProtoOrDie(R"pb(
    active_manifest {
      label: "urn:c2pa:active"
      validation {
        failures {
          code: "general.error"
          url: "self#jumbf=/c2pa/urn:c2pa:active"
        }
        informationals {
          code: "com.google.timeStamp.outOfRange"
          url: "self#jumbf=/c2pa/urn:c2pa:active"
        }
      }
    }
  )pb");

  auto result =
      IngredientResultConverter().Convert(ValidationResult(std::move(input)));
  ABSL_ASSERT_OK(result);

  EXPECT_THAT((*result)->proto(), EqualsProto(R"pb(
                ingredient_validation_results {
                  active_manifest {
                    failures {
                      code: "general.error"
                      url: "self#jumbf=/c2pa/urn:c2pa:active"
                    }
                    informationals {
                      code: "com.google.timeStamp.outOfRange"
                      url: "self#jumbf=/c2pa/urn:c2pa:active"
                    }
                  }
                }
                logging_metadata { active_manifest {} }
              )pb"));
}

TEST(IngredientResultConverterTest,
     ConvertMultipleAssertionsReferencingSameIngredient) {
  ValidationResultProto input = ParseTextProtoOrDie(R"pb(
    active_manifest {
      label: "urn:c2pa:active"
      assertions {
        label: "ingredient_assertion1"
        ingredient_v3 {
          active_manifest { url: "self#jumbf=/c2pa/urn:c2pa:ingredient1" }
          validation_results {
            active_manifest { successes { code: "claimSignature.validated" } }
          }
        }
      }
      assertions {
        label: "ingredient_assertion2"
        ingredient_v3 {
          active_manifest { url: "self#jumbf=/c2pa/urn:c2pa:ingredient1" }
          validation_results {
            active_manifest { successes { code: "claimSignature.validated" } }
          }
        }
      }
    }
    ingredient_manifests {
      label: "urn:c2pa:ingredient1"
      validation {
        successes { code: "claimSignature.validated" }
        failures { code: "ingredient_failure" url: "test://failure" }
      }
    }
  )pb");

  auto result =
      IngredientResultConverter().Convert(ValidationResult(std::move(input)));
  ABSL_ASSERT_OK(result);

  EXPECT_THAT(
      (*result)->proto(), EqualsProto(R"pb(
        ingredient_validation_results {
          ingredient_deltas {
            ingredient_assertion_uri: "self#jumbf=/c2pa/urn:c2pa:active/c2pa.assertions/ingredient_assertion1"
            validation_deltas {
              failures { code: "ingredient_failure" url: "test://failure" }
            }
          }
          ingredient_deltas {
            ingredient_assertion_uri: "self#jumbf=/c2pa/urn:c2pa:active/c2pa.assertions/ingredient_assertion2"
            validation_deltas {
              failures { code: "ingredient_failure" url: "test://failure" }
            }
          }
        }
        logging_metadata { active_manifest {} }
      )pb"));
}

TEST(IngredientResultConverterTest, ConvertChainedIngredientManifests) {
  ValidationResultProto input = ParseTextProtoOrDie(R"pb(
    active_manifest {
      label: "urn:c2pa:active"
      assertions {
        label: "assertion_for_ingredient1"
        ingredient_v3 {
          active_manifest { url: "self#jumbf=/c2pa/urn:c2pa:ingredient1" }
          validation_results {
            active_manifest { successes { code: "claimSignature.validated" } }
          }
        }
      }
    }
    ingredient_manifests {
      label: "urn:c2pa:ingredient1"
      assertions {
        label: "assertion_for_ingredient2"
        ingredient_v3 {
          active_manifest { url: "self#jumbf=/c2pa/urn:c2pa:ingredient2" }
          validation_results {
            active_manifest { successes { code: "claimSignature.validated" } }
          }
        }
      }
      validation { successes { code: "claimSignature.validated" } }
    }
    ingredient_manifests {
      label: "urn:c2pa:ingredient2"
      validation {
        successes { code: "claimSignature.validated" }
        failures { code: "chained_failure" url: "test://chained" }
      }
    }
  )pb");

  auto result =
      IngredientResultConverter().Convert(ValidationResult(std::move(input)));
  ABSL_ASSERT_OK(result);

  EXPECT_THAT(
      (*result)->proto(), EqualsProto(R"pb(
        ingredient_validation_results {
          ingredient_deltas {
            ingredient_assertion_uri: "self#jumbf=/c2pa/urn:c2pa:active/c2pa.assertions/assertion_for_ingredient1"
            validation_deltas {}
          }
          ingredient_deltas {
            ingredient_assertion_uri: "self#jumbf=/c2pa/urn:c2pa:ingredient1/c2pa.assertions/assertion_for_ingredient2"
            validation_deltas {
              failures { code: "chained_failure" url: "test://chained" }
            }
          }
        }
        logging_metadata { active_manifest {} }
      )pb"));
}

TEST(IngredientResultConverterTest, ConvertIngredientDeltasStatusVarieties) {
  ValidationResultProto input = ParseTextProtoOrDie(R"pb(
    active_manifest {
      label: "urn:c2pa:active"
      assertions {
        label: "ingredient_assertion"
        ingredient_v3 {
          active_manifest { url: "self#jumbf=/c2pa/urn:c2pa:ingredient1" }
          validation_results {
            active_manifest { successes { code: "known_success" } }
          }
        }
      }
    }
    ingredient_manifests {
      label: "urn:c2pa:ingredient1"
      validation {
        successes { code: "known_success" }
        successes { code: "new_success" url: "test://success" }
        informationals { code: "info_code" url: "test://info" }
      }
    }
  )pb");

  auto result =
      IngredientResultConverter().Convert(ValidationResult(std::move(input)));
  ABSL_ASSERT_OK(result);

  EXPECT_THAT(
      (*result)->proto(), EqualsProto(R"pb(
        ingredient_validation_results {
          ingredient_deltas {
            ingredient_assertion_uri: "self#jumbf=/c2pa/urn:c2pa:active/c2pa.assertions/ingredient_assertion"
            validation_deltas {
              successes { code: "new_success" url: "test://success" }
              informationals { code: "info_code" url: "test://info" }
            }
          }
        }
        logging_metadata { active_manifest {} }
      )pb"));
}

TEST(IngredientResultConverterTest, ConvertUnreferencedStandardIngredient) {
  ValidationResultProto input = ParseTextProtoOrDie(R"pb(
    active_manifest { label: "urn:c2pa:active" }
    ingredient_manifests { label: "urn:c2pa:unreferenced" }
  )pb");

  auto result =
      IngredientResultConverter().Convert(ValidationResult(std::move(input)));
  ABSL_ASSERT_OK(result);

  EXPECT_THAT((*result)->proto(), EqualsProto(R"pb(
                logging_metadata { active_manifest {} }
              )pb"));
}

TEST(IngredientResultConverterTest,
     ConvertMissingReferencedIngredientManifest) {
  ValidationResultProto input = ParseTextProtoOrDie(R"pb(
    active_manifest {
      label: "urn:c2pa:active"
      validation {
        informationals {
          code: "ingredient.unknownProvenance"
          url: "self#jumbf=/c2pa/urn:c2pa:active/c2pa.assertions/ingredient_v3"
        }
      }
      assertions {
        label: "ingredient_v3"
        ingredient_v3 {
          active_manifest { url: "self#jumbf=/c2pa/urn:c2pa:missing" }
        }
      }
    }
  )pb");

  auto result =
      IngredientResultConverter().Convert(ValidationResult(std::move(input)));
  ABSL_ASSERT_OK(result);

  EXPECT_THAT(
      (*result)->proto(), EqualsProto(R"pb(
        ingredient_validation_results {
          active_manifest {
            informationals {
              code: "ingredient.unknownProvenance"
              url: "self#jumbf=/c2pa/urn:c2pa:active/c2pa.assertions/ingredient_v3"
            }
          }
        }
        logging_metadata { active_manifest {} }
      )pb"));
}

TEST(IngredientResultConverterTest, ConvertMultipleLegacyIngredientManifests) {
  ValidationResultProto input = ParseTextProtoOrDie(R"pb(
    active_manifest {
      label: "urn:c2pa:active"
      assertions {
        label: "std_assertion"
        ingredient_v3 {
          active_manifest { url: "self#jumbf=/c2pa/urn:c2pa:std" }
        }
      }
      assertions {
        label: "legacy_assertion"
        ingredient_v3 {
          active_manifest { url: "self#jumbf=/c2pa/legacy_label" }
        }
      }
    }
    ingredient_manifests { label: "urn:c2pa:std" }
    ingredient_manifests { label: "legacy_label" }
  )pb");

  auto result =
      IngredientResultConverter().Convert(ValidationResult(std::move(input)));
  ABSL_ASSERT_OK(result);

  EXPECT_THAT(
      (*result)->proto(), EqualsProto(R"pb(
        ingredient_validation_results {
          ingredient_deltas {
            ingredient_assertion_uri: "self#jumbf=/c2pa/urn:c2pa:active/c2pa.assertions/std_assertion"
            validation_deltas {}
          }
          ingredient_deltas {
            ingredient_assertion_uri: "self#jumbf=/c2pa/urn:c2pa:active/c2pa.assertions/legacy_assertion"
            validation_deltas {}
          }
        }
        legacy_ingredient_metadata {
          unsupported_manifests: "legacy_label"
          unsupported_ingredient_assertion_uris: "self#jumbf=/c2pa/urn:c2pa:active/c2pa.assertions/legacy_assertion"
        }
        logging_metadata { active_manifest {} }
      )pb"));
}

TEST(IngredientResultConverterTest, ConvertCopiesSpecVersion) {
  ValidationResultProto validation_result;
  validation_result.set_spec_version("2.2.0");
  validation_result.mutable_active_manifest()
      ->mutable_validation()
      ->add_successes()
      ->set_code("code");

  auto result = IngredientResultConverter().Convert(
      ValidationResult(std::move(validation_result)));
  ABSL_ASSERT_OK(result);
  EXPECT_EQ((*result)->proto().ingredient_validation_results().spec_version(),
            "2.2.0");
}

TEST(IngredientResultConverterTest, ConvertCopiesTrustListUri) {
  ValidationResultProto validation_result;
  validation_result.set_trust_list_uri("urn:test");
  validation_result.mutable_active_manifest()
      ->mutable_validation()
      ->add_successes()
      ->set_code("code");

  auto result = IngredientResultConverter().Convert(
      ValidationResult(std::move(validation_result)));
  ABSL_ASSERT_OK(result);
  EXPECT_EQ((*result)->proto().ingredient_validation_results().trust_list_uri(),
            "urn:test");
}

TEST(IngredientResultConverterTest, ConvertCopiesManifestStoreBytes) {
  ValidationResult validation_result(ValidationResultProto(),
                                     "manifest_store_bytes");

  auto result =
      IngredientResultConverter().Convert(std::move(validation_result));
  ABSL_ASSERT_OK(result);
  EXPECT_EQ((*result)->proto().manifest_store_bytes(), "manifest_store_bytes");
}

// Records the manifests it is given and stamps a digital source type, standing
// in for enrichment that the converter deliberately does not implement.
class RecordingConsumer : public ManifestConsumer {
 public:
  absl::Status OnManifestValidated(const Manifest& manifest,
                                   bool is_active_manifest) override {
    labels_.push_back(manifest.label());
    active_manifest_labels_.push_back(is_active_manifest);
    return absl::OkStatus();
  }

  absl::Status OnIngredientValidationResultComplete(
      IngredientValidationResultProto* ingredient_result) override {
    ingredient_result->set_digital_source_type("test://digital-source-type");
    return absl::OkStatus();
  }

  const std::vector<std::string>& labels() const { return labels_; }
  const std::vector<bool>& active_manifest_labels() const {
    return active_manifest_labels_;
  }

 private:
  std::vector<std::string> labels_;
  std::vector<bool> active_manifest_labels_;
};

TEST(IngredientResultConverterTest, ConvertNotifiesTheConsumerOfEveryManifest) {
  ValidationResultProto input = ParseTextProtoOrDie(R"pb(
    active_manifest { label: "urn:c2pa:active" }
    ingredient_manifests { label: "urn:c2pa:first" }
    ingredient_manifests { label: "urn:c2pa:second" }
  )pb");
  auto consumer = std::make_unique<RecordingConsumer>();
  RecordingConsumer* consumer_ptr = consumer.get();
  // The converter owns the consumer, so it has to outlive the expectations.
  IngredientResultConverter converter(std::move(consumer));

  auto result = converter.Convert(ValidationResult(std::move(input)));
  ABSL_ASSERT_OK(result);

  EXPECT_THAT(
      consumer_ptr->labels(),
      ElementsAre("urn:c2pa:active", "urn:c2pa:first", "urn:c2pa:second"));
  EXPECT_THAT(consumer_ptr->active_manifest_labels(),
              ElementsAre(true, false, false));
  EXPECT_EQ((*result)->proto().digital_source_type(),
            "test://digital-source-type");
}

TEST(IngredientResultConverterTest,
     ConvertWithoutAConsumerLeavesDigitalSourceTypeUnset) {
  ValidationResultProto input = ParseTextProtoOrDie(R"pb(
    active_manifest {
      label: "urn:c2pa:active"
      assertions {
        actions {
          actions {
            digital_source_type: "http://cv.iptc.org/newscodes/digitalsourcetype/trainedAlgorithmicMedia"
          }
        }
      }
    }
  )pb");

  auto result =
      IngredientResultConverter().Convert(ValidationResult(std::move(input)));
  ABSL_ASSERT_OK(result);

  EXPECT_FALSE((*result)->proto().has_digital_source_type());
}

TEST(IngredientResultConverterTest, ConvertPropagatesConsumerError) {
  class FailingConsumer : public ManifestConsumer {
   public:
    absl::Status OnManifestValidated(const Manifest& manifest,
                                     bool is_active_manifest) override {
      return absl::InternalError("consumer failed");
    }
  };
  ValidationResultProto input = ParseTextProtoOrDie(R"pb(
    active_manifest { label: "urn:c2pa:active" }
  )pb");

  EXPECT_THAT(IngredientResultConverter(std::make_unique<FailingConsumer>())
                  .Convert(ValidationResult(std::move(input))),
              StatusIs(absl::StatusCode::kInternal));
}

}  // namespace
}  // namespace credentio
