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

#include <cstdint>
#include <string>

#include "absl/status/status.h"
#include "absl/status/status_macros.h"
#include "absl/status/statusor.h"
#include "absl/strings/match.h"
#include "absl/strings/string_view.h"
#include "formats/bmff/box_header.h"
#include "riegeli/bytes/reader.h"

namespace credentio {

namespace {

bool IsSupportedBrand(absl::string_view brand) {
  return brand == "qt  " || absl::StartsWith(brand, "mp4") || brand == "heic" ||
         brand == "avif" || brand == "M4A " || absl::StartsWith(brand, "iso");
}

absl::StatusOr<std::string> ExtractBrand(riegeli::Reader& input) {
  std::string brand;
  if (!input.Read(4, brand)) {
    return input.StatusOrAnnotate(absl::InternalError("failed to read brand"));
  }
  return brand;
}

}  // namespace

absl::StatusOr<bool> BmffAssessor::IsSupported(riegeli::Reader& input) const {
  int64_t starting_position = input.pos();

  bool is_supported = false;
  absl::Status iteration_status = IterateOverBmffBoxes(
      input,
      [&input,
       &is_supported](const BmffBoxHeader& box_header) -> absl::StatusOr<bool> {
        if (box_header.type == "ftyp") {
          uint64_t box_end = box_header.start + box_header.box_size;
          if (box_header.box_size < box_header.header_size + 8) {
            return false;  // Terminate loop
          }

          ABSL_ASSIGN_OR_RETURN(auto major_brand, ExtractBrand(input));
          if (IsSupportedBrand(major_brand)) {
            is_supported = true;
            return false;  // Terminate loop
          }
          if (!input.Skip(4)) {
            return input.StatusOrAnnotate(
                absl::InternalError("failed to skip minor brand"));
          }

          std::string compatible_brand;
          while (input.pos() <= box_end && box_end - input.pos() >= 4) {
            ABSL_ASSIGN_OR_RETURN(compatible_brand, ExtractBrand(input));
            if (IsSupportedBrand(compatible_brand)) {
              is_supported = true;
              return false;  // Terminate loop
            }
          }

          // We didn't find a supported brand.
          return false;  // Terminate loop
        } else if (box_header.type == "moov") {
          // We found a moov box, confident that this file is a QuickTime Movie.
          is_supported = true;
          return false;  // Terminate loop
        }

        // Only process top-level atoms.
        if (!input.Seek(box_header.start + box_header.box_size)) {
          return input.StatusOrAnnotate(
              absl::InternalError("failed to seek to end of box"));
        }
        return true;  // Continue
      });

  if (!input.Seek(starting_position) || input.pos() != starting_position) {
    return input.StatusOrAnnotate(
        absl::InternalError("failed to seek to start of asset"));
  }
  if (!iteration_status.ok() && !absl::IsDataLoss(iteration_status)) {
    return iteration_status;
  }
  if (absl::IsDataLoss(iteration_status)) {
    return false;
  }
  return is_supported;
}

}  // namespace credentio
