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

#include <cstdint>
#include <memory>
#include <utility>
#include <vector>

#include "absl/base/nullability.h"
#include "absl/container/flat_hash_map.h"
#include "absl/log/die_if_null.h"
#include "absl/status/status.h"
#include "absl/status/status_macros.h"
#include "absl/status/statusor.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "absl/types/span.h"
#include "bindings/binding_hasher.h"
#include "bindings/boxes_hash_validator.h"
#include "constants/status_codes.h"
#include "formats/asset_box.h"
#include "formats/asset_byte_info.h"
#include "formats/byte_range.h"
#include "proto/assertion.pb.h"
#include "proto/boxes_hash_assertion.pb.h"
#include "proto/manifest.pb.h"
#include "proto/validation_result.pb.h"
#include "riegeli/bytes/reader.h"
#include "utils/dual_status_tracker.h"
#include "utils/status_tracker.h"
#include "validator/result.h"
#include "validator/validation_result_internal.h"

namespace credentio {

namespace {

class BoxesHashBindingHasherTracker : public BindingHasherTracker {
 public:
  explicit BoxesHashBindingHasherTracker(StatusTracker* tracker,
                                         absl::string_view hard_binding_uri)
      : tracker_(*ABSL_DIE_IF_NULL(tracker)),
        hard_binding_uri_(hard_binding_uri) {}
  void RecordMismatch() override {
    tracker_.RecordFailure(FailureStatusCode::kAssertionBoxesHashMismatch,
                           {.url = hard_binding_uri_});
  }
  void RecordMalformed() override {
    tracker_.RecordFailure(FailureStatusCode::kAssertionBoxesHashMalformed,
                           {.url = hard_binding_uri_});
  }
  void RecordAlgorithmUnsupported() override {
    tracker_.RecordFailure(FailureStatusCode::kAlgorithmUnsupported,
                           {.url = hard_binding_uri_});
  }
  void RecordGeneralError(absl::Status error) override {
    tracker_.RecordFailure(
        FailureStatusCode::kGeneralError,
        {.url = hard_binding_uri_, .explanation = error.message()});
  }

 private:
  StatusTracker& tracker_;
  absl::string_view hard_binding_uri_;
};

absl::Status AddInclusions(const AssetBox& asset_box,
                           absl::Span<const BoxExclusion> exclusions,
                           absl::string_view hard_binding_uri,
                           StatusTracker& tracker,
                           std::vector<BindingHasher::Chunk>& inclusions) {
  uint64_t last_handled_offset = asset_box.byte_range.offset;
  for (const auto& exclusion : exclusions) {
    uint64_t exclusion_asset_offset =
        asset_box.byte_range.offset + exclusion.start();

    if (exclusion.start() >= asset_box.byte_range.length ||
        exclusion.length() >
            (asset_box.byte_range.length - exclusion.start())) {
      // Exclusion starts after the box or extends beyond the end of the box.
      tracker.RecordFailure(
          FailureStatusCode::kAssertionBoxesHashMalformed,
          {.url = hard_binding_uri,
           .explanation = "Exclusion starts after the box or extends beyond "
                          "the end of the box"});
      return absl::InvalidArgumentError(
          "Exclusion starts after the box or extends beyond the end of the "
          "box");
    }

    if (last_handled_offset < exclusion_asset_offset) {
      inclusions.push_back({
          .op = BindingHasher::Chunk::Op::kInclusion,
          .offset = last_handled_offset,
          .length = static_cast<int64_t>(exclusion_asset_offset) -
                    static_cast<int64_t>(last_handled_offset),
      });
    }
    last_handled_offset = exclusion_asset_offset + exclusion.length();
  }
  if (last_handled_offset <
      (asset_box.byte_range.offset + asset_box.byte_range.length)) {
    inclusions.push_back({
        .op = BindingHasher::Chunk::Op::kInclusion,
        .offset = last_handled_offset,
        .length = static_cast<int64_t>(asset_box.byte_range.offset +
                                       asset_box.byte_range.length) -
                  static_cast<int64_t>(last_handled_offset),
    });
  }
  return absl::OkStatus();
}

}  // namespace

absl::StatusOr<std::unique_ptr<ValidationResultProto>>
BoxesHashHardBindingValidator::Validate(
    riegeli::Reader& contents, const AssetByteInfo& asset_byte_info,
    std::unique_ptr<PartialValidationResultProto> partial_validation_result)
    const {
  const Assertion* absl_nullable assertion =
      GetAssertion(partial_validation_result.get(),
                   partial_validation_result->hard_binding_uri());
  if (assertion == nullptr) {
    return absl::InvalidArgumentError(absl::StrCat(
        "missing assertion: ", partial_validation_result->hard_binding_uri()));
  }
  if (!assertion->has_boxes_hash()) {
    return absl::InvalidArgumentError(
        absl::StrCat("assertion is not a boxes hash assertion: ",
                     partial_validation_result->hard_binding_uri()));
  }

  ABSL_ASSIGN_OR_RETURN(auto tracker,
                        DualStatusTracker::FromPartialValidationResult(
                            partial_validation_result.get()));

  Validate(contents, asset_byte_info.boxes, assertion->boxes_hash(),
           partial_validation_result->hard_binding_uri(), *tracker);

  return MakeFullValidationResult(std::move(partial_validation_result));
}

void BoxesHashHardBindingValidator::Validate(
    riegeli::Reader& contents, std::vector<AssetBox> contents_boxes,
    const BoxesHashAssertion& assertion, absl::string_view hard_binding_uri,
    StatusTracker& tracker) const {
  if (!BoxesHashValidator(assertion, hard_binding_uri,
                          /*claims_algo=*/"", tracker)
           .Validate()
           .ok()) {
    return;
  }

  // Needed to determine "unknown box" vs "out of order box"
  absl::flat_hash_map<absl::string_view, uint64_t> box_counts;
  for (const auto& box : contents_boxes) {
    box_counts[box.identifier] += 1;
  }

  int asset_box_index = 0;
  for (const auto& assertion_box_map : assertion.boxes()) {
    auto algorithm(assertion_box_map.alg());
    if (algorithm.empty()) {
      algorithm = assertion.alg();
    }

    std::vector<BindingHasher::Chunk> inclusions;
    for (int box_name_idx = 0; box_name_idx < assertion_box_map.names_size();
         ++box_name_idx) {
      const absl::string_view assertion_box_name =
          assertion_box_map.names(box_name_idx);

      if (asset_box_index >= contents_boxes.size()) {
        // Additional boxes in the assertion that are not in the asset.
        tracker.RecordFailure(FailureStatusCode::kAssertionBoxesHashMismatch,
                              {.url = hard_binding_uri});
        return;
      }

      const auto& current_asset_box = contents_boxes[asset_box_index];
      if (current_asset_box.identifier != assertion_box_name) {
        tracker.RecordFailure(
            box_counts[assertion_box_name] > 0
                ? FailureStatusCode::kAssertionBoxesHashMismatch
                : FailureStatusCode::kAssertionBoxesHashUnknownBox,
            {.url = hard_binding_uri});
        return;
      }
      --box_counts[assertion_box_name];

      if (assertion_box_name != "C2PA") {
        std::vector<BoxExclusion> exclusions;
        if (!assertion_box_map.excluded()) {
          for (const auto& exclusion : assertion_box_map.exclusions()) {
            if (exclusion.has_box_index() &&
                exclusion.box_index() > box_name_idx) {
              // Exclusion is for a box further down the line.
              break;
            }
            if (!exclusion.has_box_index() ||
                exclusion.box_index() == box_name_idx) {
              exclusions.push_back(exclusion);
            }
          }
        }

        if (!AddInclusions(current_asset_box, exclusions, hard_binding_uri,
                           tracker, inclusions)
                 .ok()) {
          return;
        }
      }
      ++asset_box_index;
    }
    BoxesHashBindingHasherTracker boxes_hash_tracker(&tracker,
                                                     hard_binding_uri);
    if (!inclusions.empty()) {
      auto hasher = BindingHasher::Create(algorithm, std::move(inclusions),
                                          boxes_hash_tracker);
      if (hasher == nullptr) {
        return;
      }
      auto digest = hasher->Digest(contents, boxes_hash_tracker);
      if (!digest.has_value()) {
        tracker.RecordFailure(
            FailureStatusCode::kGoogleInternalError,
            {.url = hard_binding_uri, .explanation = "Digest failed"});
        return;
      }
      // If the box_set is excluded, we don't care if the hash matches, just
      // that it can be hashed.
      bool required =
          !(assertion_box_map.has_excluded() && assertion_box_map.excluded());
      if (required && *digest != assertion_box_map.hash()) {
        tracker.RecordFailure(FailureStatusCode::kAssertionBoxesHashMismatch,
                              {.url = hard_binding_uri});
        return;
      }
    }
  }
  if (asset_box_index < contents_boxes.size()) {
    // Additional boxes in the asset that are not in the assertion.
    tracker.RecordFailure(FailureStatusCode::kAssertionBoxesHashUnknownBox,
                          {.url = hard_binding_uri});
    return;
  }
  tracker.RecordSuccess(SuccessStatusCode::kAssertionBoxesHashMatch,
                        {.url = hard_binding_uri});
}

}  // namespace credentio
