// 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 "assertion/actions_assertion_validator.h"

#include <string>

#include "absl/container/flat_hash_map.h"
#include "absl/container/flat_hash_set.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_format.h"
#include "absl/strings/string_view.h"
#include "constants/ingredient_relationships.h"
#include "constants/labels.h"
#include "constants/status_codes.h"
#include "proto/actions_assertion.pb.h"
#include "proto/assertion.pb.h"
#include "proto/hashed_uri.pb.h"
#include "proto/ingredient_assertion.pb.h"
#include "proto/manifest.pb.h"
#include "validator/tracker.h"

namespace credentio {

namespace {

absl::string_view Basename(absl::string_view path) {
  return path.substr(path.find_last_of('/') + 1);
}

bool RequiresParentOfRelationship(absl::string_view action) {
  return action == "c2pa.opened" || action == "c2pa.repackaged" ||
         action == "c2pa.transcoded";
}

bool RequiresComponentOfRelationship(absl::string_view action) {
  return action == "c2pa.placed" || action == "c2pa.removed";
}

bool RequiresIngredientValidation(absl::string_view action) {
  return RequiresParentOfRelationship(action) ||
         RequiresComponentOfRelationship(action);
}

template <class IngredientAssertionType>
bool ValidateIngredientRelationship(absl::string_view action,
                                    const IngredientAssertionType& ingredient,
                                    absl::string_view assertion_url,
                                    ValidationTracker& validation_tracker) {
  // 3.c.ii.A. Check that the ingredient relationship is parentOf.
  if (RequiresParentOfRelationship(action)) {
    if (ingredient.relationship() != kIngredientRelationshipParentOf) {
      validation_tracker.RecordFailure(
          FailureStatusCode::kAssertionActionIngredientMismatch,
          {.url = assertion_url,
           .explanation = absl::StrFormat(
               "action %s has wrong ingredient relationship: %s; want %s",
               action, ingredient.relationship(),
               kIngredientRelationshipParentOf)});
      return false;
    }
  }
  // 3.c.ii.B. Check that the ingredient relationship is componentOf.
  if (RequiresComponentOfRelationship(action)) {
    if (ingredient.relationship() != kIngredientRelationshipComponentOf) {
      validation_tracker.RecordFailure(
          FailureStatusCode::kAssertionActionIngredientMismatch,
          {.url = assertion_url,
           .explanation = absl::StrFormat(
               "action %s has wrong ingredient relationship: %s; "
               "want %s",
               action, ingredient.relationship(),
               kIngredientRelationshipComponentOf)});
      return false;
    }
  }
  return true;
}

// See
// https://spec.c2pa.org/specifications/specifications/2.4/specs/C2PA_Specification.html#_c2pa_actions_validation.
template <class ActionsAssertionType>
bool ValidateActions(
    const ActionsAssertionType& assertion,
    absl::flat_hash_map<std::string, const Assertion*> assertion_store,
    ValidationTracker& validation_tracker) {
  // 1. Ensure that it has an actions field.
  if (assertion.actions().empty()) {
    validation_tracker.RecordFailure(
        FailureStatusCode::kAssertionActionMalformed, {});
    return false;
  }
  for (auto i = 0; i < assertion.actions().size(); ++i) {
    const auto& action = assertion.actions(i);
    // 3.a. Ensure that it has an action field.
    if (action.action().empty()) {
      validation_tracker.RecordFailure(
          FailureStatusCode::kAssertionActionMalformed,
          {.explanation = "empty action"});
      return false;
    }
    // 3.b. If the action field is c2pa.created or c2pa.opened, it must be the
    // first action.
    if (action.action() == "c2pa.created" || action.action() == "c2pa.opened") {
      if (i != 0) {
        validation_tracker.RecordFailure(
            FailureStatusCode::kAssertionActionMalformed,
            {.explanation = "created/opened not first action"});
        return false;
      }
    }
    // 3.c. Check ingredient for certain actions.
    if (RequiresIngredientValidation(action.action())) {
      // 3.c.i. Check ingredients are present.
      if (!action.has_parameters()) {
        validation_tracker.RecordFailure(
            FailureStatusCode::kAssertionActionIngredientMismatch,
            {.explanation = absl::StrFormat("action %s missing parameters",
                                            action.action())});
        return false;
      }
      if (action.parameters().ingredients().size() == 0) {
        validation_tracker.RecordFailure(
            FailureStatusCode::kAssertionActionIngredientMismatch,
            {.explanation = absl::StrFormat("action %s missing ingredients",
                                            action.action())});
        return false;
      }
      // 3.c.ii. For each ingredient, check that it has a url and it is valid.
      for (const auto& ingredient : action.parameters().ingredients()) {
        if (!ingredient.has_url() || ingredient.url().empty()) {
          validation_tracker.RecordFailure(
              FailureStatusCode::kAssertionActionIngredientMismatch,
              {.explanation = absl::StrFormat(
                   "action %s missing ingredient url", action.action())});
          return false;
        }
        auto label = Basename(ingredient.url());
        if (!assertion_store.contains(label)) {
          validation_tracker.RecordFailure(
              FailureStatusCode::kAssertionActionIngredientMismatch,
              {.explanation = absl::StrFormat(
                   "action %s missing ingredient assertion", action.action())});
          return false;
        }
        auto* assertion = assertion_store[label];
        std::string assertion_url = absl::StrCat(
            kAssertionStoreLabel, kManifestLabelDelimiter, assertion->label());
        if (assertion->has_ingredient_v3()) {
          if (!ValidateIngredientRelationship(
                  action.action(), assertion->ingredient_v3(), assertion_url,
                  validation_tracker)) {
            return false;
          }
        } else {
          validation_tracker.RecordFailure(
              FailureStatusCode::kAssertionActionIngredientMismatch,
              {.url = assertion_url,
               .explanation = absl::StrFormat(
                   "action %s missing ingredient assertion", action.action())});
          return false;
        }
      }
    }
    // 3.d. If the action is c2pa.redacted, check that the redacted field that
    // is a member of the parameters object for the presence of a JUMBF URI and
    // that the URI resolves to an assertion.
    if (action.action() == "c2pa.redacted") {
      if (action.parameters().redacted_uri().empty()) {
        validation_tracker.RecordFailure(
            FailureStatusCode::kAssertionActionRedactionMismatch,
            {.explanation = absl::StrFormat(
                 "action %s missing redacted in parameters", action.action())});
        return false;
      }
      auto redacted_label = Basename(action.parameters().redacted_uri());
      if (!assertion_store.contains(redacted_label)) {
        validation_tracker.RecordFailure(
            FailureStatusCode::kAssertionActionRedactionMismatch,
            {.explanation = absl::StrFormat(
                 "action %s missing redacted assertion", action.action())});
        return false;
      }
    }
  }
  return true;
}

// 2. Check the first action in each actions assertion.
template <class ActionsAssertionType>
bool ValidateFirstAction(absl::string_view label,
                         const ActionsAssertionType& assertion,
                         bool is_first_action_assertion,
                         ValidationTracker& validation_tracker) {
  bool is_created_or_opened =
      assertion.actions_size() > 0 &&
      (assertion.actions(0).action() == "c2pa.created" ||
       assertion.actions(0).action() == "c2pa.opened");
  if (is_first_action_assertion && !is_created_or_opened) {
    validation_tracker.RecordFailure(
        FailureStatusCode::kAssertionActionMalformed,
        {.explanation = "the first action is not c2pa.created or c2pa.opened"});
    return false;
  }
  if (is_created_or_opened && !is_first_action_assertion) {
    validation_tracker.RecordFailure(
        FailureStatusCode::kAssertionActionMalformed,
        {.explanation = "c2pa.created or c2pa.opened is not the first action"});
    return false;
  }
  return true;
}

}  // namespace

bool ActionsAssertionValidator::Validate(
    const Manifest& manifest, ValidationTracker& validation_tracker) const {
  absl::flat_hash_map<std::string, const Assertion*> assertion_store;
  for (const auto& assertion : manifest.assertions()) {
    assertion_store[assertion.label()] = &assertion;
  }
  absl::flat_hash_set<std::string> created_assertions;
  created_assertions.reserve(manifest.claim().created_assertions_size());
  for (const auto& assertion : manifest.claim().created_assertions()) {
    created_assertions.insert(std::string(Basename(assertion.url())));
  }
  bool is_first_action_assertion = true;
  auto validate_actions_assertion = [&](absl::string_view label,
                                        const auto& actions_assertion) -> bool {
    if (!ValidateActions(actions_assertion, assertion_store,
                         validation_tracker)) {
      return false;
    }
    if (created_assertions.contains(label) &&
        !ValidateFirstAction(label, actions_assertion,
                             is_first_action_assertion, validation_tracker)) {
      return false;
    }
    is_first_action_assertion = false;
    return true;
  };

  for (const auto& assertion : manifest.assertions()) {
    if (assertion.has_actions_v1() &&
        !validate_actions_assertion(assertion.label(),
                                    assertion.actions_v1())) {
      return false;
    }
    if (assertion.has_actions() &&
        !validate_actions_assertion(assertion.label(), assertion.actions())) {
      return false;
    }
  }
  return true;
}

}  // namespace credentio
