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

#include "absl/container/flat_hash_map.h"
#include "absl/container/flat_hash_set.h"
#include "absl/hash/hash.h"
#include "absl/status/status_macros.h"
#include "absl/status/statusor.h"
#include "absl/strings/match.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "absl/strings/strip.h"
#include "google/protobuf/repeated_ptr_field.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 "validator/ingredient_result.h"
#include "validator/manifest_consumer.h"
#include "validator/result.h"

namespace credentio {
namespace {

bool IsLegacyManifestLabel(absl::string_view manifest_label) {
  return !absl::StartsWith(manifest_label, "urn:c2pa");
}

std::string GetAssertionUri(absl::string_view manifest_label,
                            const Assertion& assertion) {
  return absl::StrCat("self#jumbf=/c2pa/", manifest_label, "/c2pa.assertions/",
                      assertion.label());
}

std::optional<std::string> ExtractTargetManifestLabel(
    const IngredientAssertionV3& ingredient_v3) {
  if (ingredient_v3.has_active_manifest()) {
    absl::string_view url = ingredient_v3.active_manifest().url();
    if (absl::ConsumePrefix(&url, "self#jumbf=/c2pa/")) {
      return std::string(url);
    }
  }
  return std::nullopt;
}

struct ValidationStatusHash {
  size_t operator()(const ValidationStatus& status) const {
    return absl::HashOf(status.code(), status.url());
  }
};
struct ValidationStatusEqual {
  bool operator()(const ValidationStatus& lhs,
                  const ValidationStatus& rhs) const {
    return lhs.code() == rhs.code() && lhs.url() == rhs.url();
  }
};

using ValidationStatusHashSet =
    absl::flat_hash_set<ValidationStatus, ValidationStatusHash,
                        ValidationStatusEqual>;

ValidationStatusHashSet GetIngredientAssertionValidationStatus(
    const Assertion& assertion) {
  ValidationStatusHashSet statuses;
  if (assertion.has_ingredient_v3()) {
    const ValidationStatusSet& assertion_results =
        assertion.ingredient_v3().validation_results().active_manifest();
    statuses.insert(assertion_results.successes().begin(),
                    assertion_results.successes().end());
    statuses.insert(assertion_results.failures().begin(),
                    assertion_results.failures().end());
    statuses.insert(assertion_results.informationals().begin(),
                    assertion_results.informationals().end());
  }
  return statuses;
}

bool IsHardBindingSuccessCode(absl::string_view code) {
  return code == "com.google.assertion.dataHash.match" ||
         code == "com.google.assertion.bmffHash.match" ||
         code == "com.google.assertion.boxesHash.match" ||
         code == "com.google.assertion.collectionHash.match" ||
         code == "assertion.dataHash.match" ||
         code == "assertion.bmffHash.match" ||
         code == "assertion.boxesHash.match" ||
         code == "assertion.collectionHash.match";
}

google::protobuf::RepeatedPtrField<ValidationStatus> ComputeStatusDeltas(
    const google::protobuf::RepeatedPtrField<ValidationStatus>& current,
    const ValidationStatusHashSet& assertion) {
  google::protobuf::RepeatedPtrField<ValidationStatus> deltas;
  for (const auto& status : current) {
    if (!assertion.contains(status) ||
        IsHardBindingSuccessCode(status.code())) {
      ValidationStatus* delta = deltas.Add();
      delta->set_code(status.code());
      delta->set_url(status.url());
    }
  }
  return deltas;
}

ValidationStatusSet ComputeValidationDeltas(
    const ValidationStatusSet& current_results,
    const ValidationStatusHashSet& assertion_results) {
  ValidationStatusSet status_set_deltas;
  *status_set_deltas.mutable_successes() =
      ComputeStatusDeltas(current_results.successes(), assertion_results);
  *status_set_deltas.mutable_failures() =
      ComputeStatusDeltas(current_results.failures(), assertion_results);
  *status_set_deltas.mutable_informationals() =
      ComputeStatusDeltas(current_results.informationals(), assertion_results);
  return status_set_deltas;
}

struct ReferencingIngredientAssertion {
  const Assertion* assertion;
  std::string assertion_uri;
};

}  // namespace

absl::StatusOr<std::unique_ptr<IngredientValidationResultProto>>
IngredientResultConverter::ConvertProto(
    const ValidationResultProto& validation_result) const {
  auto result = std::make_unique<IngredientValidationResultProto>();

  if (!validation_result.media_type().empty()) {
    result->set_media_type(validation_result.media_type());
  }

  if (validation_result.active_manifest().has_validation()) {
    *result->mutable_ingredient_validation_results()
         ->mutable_active_manifest() =
        validation_result.active_manifest().validation();
  }

  if (!validation_result.spec_version().empty()) {
    result->mutable_ingredient_validation_results()->set_spec_version(
        validation_result.spec_version());
  }
  if (!validation_result.trust_list_uri().empty()) {
    result->mutable_ingredient_validation_results()->set_trust_list_uri(
        validation_result.trust_list_uri());
  }

  // Populate logging_metadata.
  auto* active_manifest_info =
      result->mutable_logging_metadata()->mutable_active_manifest();
  if (validation_result.active_manifest().claim().has_claim_generator_info()) {
    *active_manifest_info->mutable_claim_generator() =
        validation_result.active_manifest().claim().claim_generator_info();
  }
  if (validation_result.active_manifest().claim().has_signature_info()) {
    *active_manifest_info->mutable_signature() =
        validation_result.active_manifest().claim().signature_info();
  }

  // Populate legacy_ingredient_metadata.
  if (IsLegacyManifestLabel(validation_result.active_manifest().label())) {
    auto* legacy_metadata = result->mutable_legacy_ingredient_metadata();
    legacy_metadata->set_is_legacy_ingredient(true);
    legacy_metadata->add_unsupported_manifests(
        validation_result.active_manifest().label());
  }

  // Populate ingredient_deltas.
  absl::flat_hash_map<std::string, std::vector<ReferencingIngredientAssertion>>
      referencing_assertions;

  auto process_manifest = [&](const Manifest& m) {
    for (const auto& a : m.assertions()) {
      if (a.has_ingredient_v3()) {
        auto target_label = ExtractTargetManifestLabel(a.ingredient_v3());
        if (target_label.has_value()) {
          referencing_assertions[*target_label].push_back(
              {.assertion = &a,
               .assertion_uri = GetAssertionUri(m.label(), a)});
        }
      }
    }
  };

  process_manifest(validation_result.active_manifest());
  for (const auto& m : validation_result.ingredient_manifests()) {
    process_manifest(m);
  }

  for (const auto& m : validation_result.ingredient_manifests()) {
    auto it = referencing_assertions.find(m.label());
    if (it != referencing_assertions.end()) {
      for (const auto& ref : it->second) {
        auto* delta = result->mutable_ingredient_validation_results()
                          ->add_ingredient_deltas();
        delta->set_ingredient_assertion_uri(ref.assertion_uri);
        *delta->mutable_validation_deltas() = ComputeValidationDeltas(
            m.validation(),
            GetIngredientAssertionValidationStatus(*ref.assertion));
        if (IsLegacyManifestLabel(m.label())) {
          auto* legacy_metadata = result->mutable_legacy_ingredient_metadata();
          legacy_metadata->add_unsupported_manifests(m.label());
          legacy_metadata->add_unsupported_ingredient_assertion_uris(
              ref.assertion_uri);
        }
      }
    } else {
      if (IsLegacyManifestLabel(m.label())) {
        auto* legacy_metadata = result->mutable_legacy_ingredient_metadata();
        legacy_metadata->add_unsupported_manifests(m.label());
      }
    }
  }

  // Let the consumer populate the fields the converter does not derive itself,
  // e.g. digital_source_type.
  if (consumer_ != nullptr) {
    ABSL_RETURN_IF_ERROR(consumer_->OnManifestValidated(
        validation_result.active_manifest(), /*is_active_manifest=*/true));
    for (const auto& m : validation_result.ingredient_manifests()) {
      ABSL_RETURN_IF_ERROR(
          consumer_->OnManifestValidated(m, /*is_active_manifest=*/false));
    }
    ABSL_RETURN_IF_ERROR(
        consumer_->OnIngredientValidationResultComplete(result.get()));
  }

  return result;
}

absl::StatusOr<std::unique_ptr<IngredientResult>>
IngredientResultConverter::Convert(ValidationResult validation_result) const {
  ABSL_ASSIGN_OR_RETURN(std::unique_ptr<IngredientValidationResultProto> proto,
                        ConvertProto(validation_result.proto()));
  if (!validation_result.manifest_store_bytes().empty()) {
    proto->set_manifest_store_bytes(
        validation_result.release_manifest_store_bytes());
  }
  return std::make_unique<IngredientResult>(std::move(proto));
}

}  // namespace credentio
