// 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 "jumbf/internal/consume_box.h"

#include <cstddef>
#include <cstdint>

#include "absl/log/check.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "jumbf/internal/intermediate.h"
#include "jumbf/internal/serialization_utils.h"

namespace jumbf_internal {

absl::StatusOr<IntermediateBox> ConsumeBox(absl::string_view* input,
                                           bool allow_implicit_length) {
  absl::string_view temp_input = *input;

  auto lbox = ConsumeInteger<uint32_t>(&temp_input);
  if (!lbox.ok()) {
    return absl::Status(
        lbox.status().code(),
        absl::StrCat("cannot read LBox value: ", lbox.status().message()));
  }

  auto tbox = ConsumeInteger<uint32_t>(&temp_input);
  if (!tbox.ok()) {
    return absl::Status(
        tbox.status().code(),
        absl::StrCat("cannot read TBox value: ", tbox.status().message()));
  }
  uint64_t box_length;

  if (*lbox == 0) {
    if (allow_implicit_length) {
      box_length = input->length();
    } else {
      return absl::InvalidArgumentError(
          R"(LBox is 0, indicating box extends to end of input, but context does not allow for implicit box lengths; implicit boxes are only allowed if they are the last box in the file, and if they are contained within a super box, that super box must also have an implicit length)");
    }

  } else if (*lbox == 1) {
    auto xlbox = ConsumeInteger<uint64_t>(&temp_input);
    if (!xlbox.ok()) {
      return absl::Status(
          xlbox.status().code(),
          absl::StrCat("cannot read XLBox value: ", xlbox.status().message()));
    }
    if (*xlbox < 16) {
      return absl::InvalidArgumentError(absl::StrCat(
          "XLBox is ", *xlbox,
          ", which is less than the number of bytes already consumed by "
          "this box's header"));
    }
    box_length = *xlbox;
  } else if (*lbox <= 7) {
    return absl::InvalidArgumentError(absl::StrCat(
        "LBox is ", *lbox, "; LBox values 2-7 are reserved by the standard"));
  } else {
    box_length = *lbox;
  }

  if (box_length > input->length()) {
    return absl::InvalidArgumentError(absl::StrCat(
        "not enough input bytes for declared box size; have ", input->length(),
        " input bytes, box declares its size as ", box_length, " bytes"));
  }

  size_t header_bytes = temp_input.data() - input->data();
  absl::string_view serialized = input->substr(0, box_length);
  input->remove_prefix(box_length);

  return IntermediateBox{
      .payload = temp_input.substr(0, box_length - header_bytes),
      .serialized = serialized,
      .type = *tbox,
      .implicit_length = *lbox == 0,
  };
}

}  // namespace jumbf_internal
