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

#include <cstdint>
#include <memory>
#include <optional>
#include <string>
#include <vector>

#include "absl/base/nullability.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "bindings/binding_hasher.h"
#include "formats/bmff/box_header.h"
#include "formats/bmff/box_matcher.h"
#include "proto/bmff_based_hash_assertion.pb.h"
#include "riegeli/bytes/reader.h"
#include "utils/byte_writers.h"

namespace credentio {

namespace {

std::string Uint64ToBytes(uint64_t value) {
  std::vector<uint8_t> bytes;
  bytes.reserve(sizeof(uint64_t));
  WriteUint64NetworkOrder(value, &bytes);
  return std::string(reinterpret_cast<const char*>(bytes.data()), bytes.size());
}

absl_nullable std::unique_ptr<BindingHasher> BuildBmffV2Hasher(
    const BmffBasedHashAssertion& bmff_hash, riegeli::Reader& file_contents,
    BindingHasherTracker& tracker) {
  // Build box matchers from the assertion.
  std::vector<BMFFBoxMatcher> matchers;
  matchers.reserve(bmff_hash.exclusions_size());
  for (const auto& bmff_range : bmff_hash.exclusions()) {
    matchers.emplace_back(bmff_range, &file_contents);
  }

  // Match boxes and build exclusion and insertion chunks for the hasher.
  std::vector<BindingHasher::Chunk> chunks;
  absl::Status iterator_status = IterateOverBmffBoxes(
      file_contents,
      [&chunks, &matchers](const BmffBoxHeader& box) -> absl::StatusOr<bool> {
        std::vector<BMFFBoxMatcher::Range> exclusions;
        bool is_entire_box_excluded = false;
        for (const auto& matcher : matchers) {
          if (matcher.Matches(box)) {
            exclusions = matcher.MatchedRanges(box);
            is_entire_box_excluded = matcher.IsMatchingEntireBox();
            break;
          }
        }
        if (!is_entire_box_excluded && box.IsRootBox()) {
          chunks.push_back({.op = BindingHasher::Chunk::Op::kInsertion,
                            .offset = box.start,
                            .additional_data = Uint64ToBytes(box.start)});
        }
        for (const auto& exclusion : exclusions) {
          chunks.push_back({.op = BindingHasher::Chunk::Op::kExclusion,
                            .offset = exclusion.offset,
                            .length = exclusion.length});
        }
        return true;
      });
  if (!iterator_status.ok()) {
    tracker.RecordGeneralError(iterator_status);
    return nullptr;
  }
  return BindingHasher::Create(bmff_hash.alg(), chunks, tracker);
}
}  // namespace

std::optional<std::string> BmffBindingHasher::Digest(
    riegeli::Reader& input) const {
  auto hasher = BuildBmffV2Hasher(assertion_, input, tracker_);
  if (hasher == nullptr) {
    return std::nullopt;
  }
  return hasher->Digest(input, tracker_);
}

}  // namespace credentio
