// 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 "bindings/boxes_hash_validator.h"

#include <cstdint>
#include <limits>

#include "absl/status/status.h"
#include "absl/status/status_macros.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "absl/types/span.h"
#include "constants/status_codes.h"
#include "crypto/algorithms.h"
#include "proto/boxes_hash_assertion.pb.h"

namespace credentio {
namespace {

constexpr absl::string_view kSingleZeroByte("\0", 1);

absl::string_view DetermineAlgorithm(
    absl::Span<const absl::string_view> algos) {
  absl::string_view algo_to_use = "";
  for (const auto& alg : algos) {
    if (!alg.empty()) {
      algo_to_use = alg;
      break;
    }
  }
  return algo_to_use;
}

}  // namespace

absl::Status BoxesHashValidator::Validate() {
  if (assertion_.boxes().empty()) {
    return LogFailure(FailureStatusCode::kAssertionBoxesHashMalformed,
                      "box-map.boxes is empty");
  }

  for (const auto& box_hash_map : assertion_.boxes()) {
    ABSL_RETURN_IF_ERROR(ValidateBoxHashMap(box_hash_map));
  }

  return absl::OkStatus();
}

absl::Status BoxesHashValidator::LogFailure(FailureStatusCode failure_code,
                                            absl::string_view explanation) {
  tracker_.RecordFailure(
      failure_code, {.url = hard_binding_uri_, .explanation = explanation});
  return absl::InvalidArgumentError(explanation);
}

void BoxesHashValidator::LogAdditionalExclusionsPresent() {
  if (!found_additional_exclusions_) {
    found_additional_exclusions_ = true;
    tracker_.RecordInformational(
        InformationalStatusCode::kAssertionBoxesHashAdditionalExclusionsPresent,
        {.url = hard_binding_uri_});
  }
}

absl::Status BoxesHashValidator::ValidateBoxHashMap(
    const BoxHash& box_hash_map) {
  if (box_hash_map.names().empty()) {
    return LogFailure(FailureStatusCode::kAssertionBoxesHashMalformed,
                      "box-map.names is empty");
  }

  if (box_hash_map.hash().empty()) {
    return LogFailure(FailureStatusCode::kAssertionBoxesHashMismatch,
                      "box-map.hash is empty");
  }

  absl::string_view algo =
      DetermineAlgorithm({box_hash_map.alg(), assertion_.alg(), claims_algo_});
  if (!ParseHashAlgorithm(algo).ok()) {
    return LogFailure(FailureStatusCode::kAlgorithmUnsupported,
                      absl::StrCat("Algorithm not supported: ", algo));
  }

  bool contains_c2pa_box = false;
  for (const auto& name : box_hash_map.names()) {
    if (name == "C2PA") {
      contains_c2pa_box = true;
      if (box_hash_map.names_size() != 1) {
        return LogFailure(FailureStatusCode::kAssertionBoxesHashMalformed,
                          "C2PA box must be the only name in the names array");
      }
      if (box_hash_map.hash() != kSingleZeroByte) {
        // Is this the right error code? It's not really a mismatch.
        return LogFailure(FailureStatusCode::kAssertionBoxesHashMismatch,
                          "C2PA box hash is not a single 0 byte");
      }
    }
  }

  if (box_hash_map.excluded()) {
    return ValidateExclusion(box_hash_map, contains_c2pa_box);
  } else if (!box_hash_map.exclusions().empty()) {
    return ValidateExclusionRanges(box_hash_map, contains_c2pa_box);
  }

  return absl::OkStatus();
}

absl::Status BoxesHashValidator::ValidateExclusion(const BoxHash& box_hash_map,
                                                   bool contains_c2pa_box) {
  if (!contains_c2pa_box) {
    LogAdditionalExclusionsPresent();
  }
  return absl::OkStatus();
}

absl::Status BoxesHashValidator::ValidateExclusionRanges(
    const BoxHash& box_hash_map, bool contains_c2pa_box) {
  int64_t last_box_index = -1;
  int64_t last_start = -1;
  int64_t last_end_offset = -1;

  for (const auto& exclusion : box_hash_map.exclusions()) {
    if (exclusion.start() < 0 || exclusion.length() < 0) {
      return LogFailure(
          FailureStatusCode::kAssertionBoxesHashMalformed,
          "box-map.start and box-map.length must be non-negative");
    }
    if (std::numeric_limits<int64_t>::max() - exclusion.start() <
        exclusion.length()) {
      return LogFailure(FailureStatusCode::kAssertionBoxesHashMalformed,
                        "box-map.start + box-map.length overflows");
    }

    if (!exclusion.has_box_index() && box_hash_map.names_size() > 1) {
      return LogFailure(FailureStatusCode::kAssertionBoxesHashMalformed,
                        "box-map.boxIndex is required when there is more "
                        "than one box");
    } else if (exclusion.has_box_index() &&
               (exclusion.box_index() < 0 ||
                exclusion.box_index() >= box_hash_map.names_size())) {
      return LogFailure(FailureStatusCode::kAssertionBoxesHashMalformed,
                        "box-map.boxIndex is out of range");
    }

    int64_t new_box_index =
        exclusion.has_box_index() ? exclusion.box_index() : 0;
    if (last_box_index == -1 || last_box_index < new_box_index) {
      // First exclusion of this box, so just set the last box index.
      last_box_index = new_box_index;
      last_start = exclusion.start();
      last_end_offset = last_start + exclusion.length();
      continue;
    } else if (new_box_index < last_box_index) {
      // Next box index should be greater or equal to the last one.
      return LogFailure(FailureStatusCode::kAssertionBoxesHashMalformed,
                        "box-map.boxIndex is not in order");
    } else if (new_box_index == last_box_index) {
      if (last_start >= exclusion.start() ||
          last_end_offset > exclusion.start()) {
        return LogFailure(FailureStatusCode::kAssertionBoxesHashMalformed,
                          "box-map.start is overlapping with the last "
                          "box-map.start");
      }
      last_start = exclusion.start();
      last_end_offset = last_start + exclusion.length();
    }
  }

  if (!contains_c2pa_box) {
    LogAdditionalExclusionsPresent();
  }

  return absl::OkStatus();
}

}  // namespace credentio
