// 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 "formats/bmff/box_matcher.h"

#include <cstdint>
#include <string>
#include <vector>

#include "formats/bmff/box_header.h"
#include "formats/bmff/xpath.h"
#include "proto/bmff_based_hash_assertion.pb.h"

namespace credentio {
namespace {

uint32_t NetworkUInt24(std::string value) {
  uint32_t result = 0;
  for (int i = 0; i < 3; ++i) {
    uint8_t byte = (i < value.size()) ? static_cast<uint8_t>(value[i]) : 0;
    result = (result << 8) | byte;
  }
  return result;
}

bool MatchLength(const BmffRange& bmff_range, const BmffBoxHeader& header) {
  if (!bmff_range.has_length()) {
    return true;
  }
  return header.box_size == bmff_range.length();
}

bool MatchVersion(const BmffRange& bmff_range, const BmffBoxHeader& header) {
  if (!bmff_range.has_version()) {
    return true;
  }
  return header.version == bmff_range.version();
}

bool MatchFlags(const BmffRange& bmff_range, const BmffBoxHeader& header) {
  if (!bmff_range.has_flags()) {
    return true;
  }
  if (!header.IsFullBox()) {
    return false;
  }
  if (!bmff_range.has_exact() || bmff_range.exact()) {
    return header.flags == bmff_range.flags();
  }
  auto desired_flags = NetworkUInt24(std::string(bmff_range.flags()));
  auto box_flags = NetworkUInt24(header.flags);
  return (desired_flags & box_flags) == desired_flags;
}

}  // namespace

bool BMFFBoxMatcher::Matches(BmffBoxHeader header) const {
  if (!(XPathMatcher(bmff_range_.xpath()).Matches(header.xpath)) ||
      !MatchLength(bmff_range_, header) || !MatchVersion(bmff_range_, header) ||
      !MatchFlags(bmff_range_, header)) {
    return false;
  }
  for (const auto& data : bmff_range_.data()) {
    uint64_t offset = header.start + data.offset();
    input_.Seek(offset);
    if (input_.pos() != offset) {
      return false;
    }
    std::string value;
    if (!input_.Read(data.value().size(), value)) {
      return false;
    }
    if (value != data.value()) {
      return false;
    }
  }
  return true;
}

std::vector<BMFFBoxMatcher::Range> BMFFBoxMatcher::MatchedRanges(
    BmffBoxHeader header) const {
  std::vector<Range> ranges;
  if (bmff_range_.subsets_size() == 0) {
    ranges.push_back({.offset = header.start,
                      .length = static_cast<int64_t>(header.box_size)});
    return ranges;
  }
  for (const auto& subset : bmff_range_.subsets()) {
    int64_t offset = header.start + subset.offset();
    int64_t end = header.start + subset.offset() + subset.length();
    if (offset > end) {
      // Invalid subset.
      continue;
    }
    if (subset.length() == 0 || end > header.start + header.box_size) {
      end = header.start + header.box_size;
    }
    ranges.push_back(
        {.offset = header.start + subset.offset(), .length = end - offset});
  }
  return ranges;
}
}  // namespace credentio
