// 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.
//

#ifndef THIRD_PARTY_CREDENTIO_FORMATS_BMFF_BOX_HEADER_H_
#define THIRD_PARTY_CREDENTIO_FORMATS_BMFF_BOX_HEADER_H_

#include <array>
#include <cstdint>
#include <cstring>
#include <string>

#include "absl/base/no_destructor.h"
#include "absl/container/flat_hash_set.h"
#include "absl/functional/function_ref.h"
#include "absl/status/statusor.h"
#include "absl/strings/match.h"
#include "absl/strings/string_view.h"
#include "formats/byte_range.h"
#include "riegeli/bytes/reader.h"
#include "riegeli/bytes/writer.h"

namespace credentio {

// A BMFF box header for reading.
struct BmffBoxHeader {
  uint64_t start;        // Absolute offset of the box header within input.
  uint64_t box_size;     // Includes header and version/flags when present.
  uint64_t header_size;  // Size of the header.
  // Size of version and flags, if it is a full box (atom).
  uint64_t version_and_flags_size = 0;
  std::string type;            // The type of the box.
  std::string xpath;           // The XPath of the box, like "/moov[1]/pssh".
  std::string user_type = "";  // Only present in UUID.
  // Version and flags only present in a full box (atom) or UUID.
  // Check `version_and_flags_size > 0` to determine if these are present.
  uint8_t version = 0;
  std::string flags = "";

  // Returns true if the box is at the root level (has no parent).
  bool IsRootBox() const {
    return xpath.empty() || !absl::StrContains(xpath.substr(1), "/");
  }

  // Returns true if the box is a Full Box (contains version and flags).
  bool IsFullBox() const { return version_and_flags_size > 0; }

  // Returns true if the box is a container box that can have sub-boxes.
  bool IsContainerBox() const;
};

inline bool operator==(const BmffBoxHeader& a, const BmffBoxHeader& b) {
  return a.start == b.start && a.box_size == b.box_size &&
         a.header_size == b.header_size &&
         a.version_and_flags_size == b.version_and_flags_size &&
         a.type == b.type && a.xpath == b.xpath && a.user_type == b.user_type &&
         a.version == b.version && a.flags == b.flags;
}

// A BMFF box header for writing.
struct BmffBox {
  std::string type;
  std::string user_type;
  uint8_t version = 0;
  std::string flags;
  uint64_t data_size = 0;
};

// Reads a BMFF box header from the input reader.
// Returns the parsed header or an error status.
absl::StatusOr<BmffBoxHeader> ReadBmffBoxHeader(riegeli::Reader& input);

// Writes the header of the given BMFF box and returns the number of written
// bytes.
absl::StatusOr<int64_t> WriteBmffBoxHeader(const BmffBox& box,
                                           riegeli::Writer& destination);

// Returns the size of the encoded BMFF box header.
int64_t BmffBoxHeaderSize(const BmffBox& box);

// Returns true if the given box type is a Full Box.
inline bool IsBmffFullBox(absl::string_view type);

// The function signature for processing a BMFF box. The function is called for
// each box in a BMFF file.
using BmffBoxProcessor =
    absl::FunctionRef<absl::StatusOr<bool>(const BmffBoxHeader&)>;

// Iterates over all BMFF boxes in the given reader, including sub-boxes in a
// depth-first traversal, calling the given `processor` function for each box.
// The method will seek to position 0 in the reader before iterating.
//
// The `processor` function controls the iteration by returning an
// `absl::StatusOr<bool>`:
// - Return `true` to continue iterating over subsequent boxes.
// - Return `false` to stop iterating early. `IterateOverBmffBoxes` will stop
//   and return `absl::OkStatus()`.
// - Return an error status to abort iteration immediately and propagate the
//   error back to the caller.
//
// The processor can also affect iteration by seeking the reader:
// - For container boxes, sub-box iteration will start reading from wherever
//   the processor leaves the reader.
// - To skip processing sub-boxes of a container box, the processor can seek
//   the reader to the end of the current box (`box.start + box.box_size`).
// - The iterator will always reset the reader position to the end of the
//   current box before proceeding to the next sibling box.
absl::Status IterateOverBmffBoxes(riegeli::Reader& reader,
                                  BmffBoxProcessor processor);

// Reads all BMFF box headers from the given input, including sub-boxes.
absl::StatusOr<std::vector<BmffBoxHeader>> ReadBmffBoxHeaders(
    riegeli::Reader& input);

// Locates the insertion point for the C2PA manifest in the given reader.
absl::StatusOr<ByteRange> LocateManifestInsertionPoint(riegeli::Reader& reader);

namespace credentio_internal {

// This list mirrors the C2PA SDK's implementation:
// https://github.com/contentauth/c2pa-rs/blob/main/sdk/src/asset_handlers/bmff_io.rs#L58.
constexpr std::array<std::string_view, 80> kFullBoxTypes = {
    "pdin", "mvhd", "tkhd", "mdhd", "hdlr", "nmhd", "elng", "stsd", "stdp",
    "stts", "ctts", "cslg", "stss", "stsh", "stdp", "elst", "dref", "stsz",
    "stz2", "stsc", "stco", "co64", "padb", "subs", "saiz", "saio", "mehd",
    "trex", "mfhd", "tfhd", "trun", "tfra", "mfro", "tfdt", "leva", "trep",
    "assp", "sbgp", "sgpd", "csgp", "cprt", "tsel", "kind", "meta", "xml ",
    "bxml", "iloc", "pitm", "ipro", "infe", "iinf", "iref", "ipma", "schm",
    "fiin", "fpar", "fecr", "gitn", "fire", "stri", "stsg", "stvi", "csch",
    "sidx", "ssix", "prft", "srpp", "vmhd", "smhd", "srat", "chnl", "dmix",
    "txtC", "mime", "uri ", "uriI", "hmhd", "sthd", "vvhd", "medc"};

constexpr bool AllTypesHaveSize4() {
  for (const std::string_view type : kFullBoxTypes) {
    if (type.size() != 4) {
      return false;
    }
  }
  return true;
}

// Requires that `type` is exactly 4 bytes long.
inline uint32_t TypeAsUint32(absl::string_view type) {
  uint32_t ret;
  std::memcpy(&ret, type.data(), sizeof(ret));
  return ret;
}

}  // namespace credentio_internal

bool IsBmffFullBox(absl::string_view type) {
  static_assert(
      credentio_internal::AllTypesHaveSize4(),
      "The following algorithm works only if all types are 4 bytes long.");
  static const absl::NoDestructor<absl::flat_hash_set<uint32_t>>
      kFullBoxTypesSet([]() {
        absl::flat_hash_set<uint32_t> ret;
        ret.reserve(credentio_internal::kFullBoxTypes.size());
        for (const std::string_view type : credentio_internal::kFullBoxTypes) {
          ret.insert(credentio_internal::TypeAsUint32(type));
        }
        return ret;
      }());
  return type.size() == 4 &&
         kFullBoxTypesSet->contains(credentio_internal::TypeAsUint32(type));
}

}  // namespace credentio

#endif  // THIRD_PARTY_CREDENTIO_FORMATS_BMFF_BOX_HEADER_H_
