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

#include <cstddef>
#include <cstdint>
#include <limits>
#include <utility>

#include "absl/log/check.h"
#include "absl/status/status.h"
#include "absl/status/status_macros.h"
#include "absl/strings/cord.h"
#include "jumbf/constants.h"
#include "jumbf/encode_params.h"
#include "jumbf/internal/serialization_utils.h"
#include "riegeli/base/types.h"
#include "riegeli/bytes/backward_writer.h"
#include "uuid/uuid.h"

namespace jumbf {

using ::jumbf_internal::WriteInteger;
using ::jumbf_internal::WriteNulTerminated;
using ::jumbf_internal::WritePadding;
using ::jumbf_internal::WriteRaw;

static_assert(std::numeric_limits<uint64_t>::max() >=
                  std::numeric_limits<size_t>::max(),
              "This library converts from `size_t` to `uint64_t` when writing "
              "XLBox values.");

absl::Status EncodePaddingBox(uint64_t padding_size,
                              riegeli::BackwardWriter* writer) {
  ABSL_RETURN_IF_ERROR(WritePadding(padding_size, writer));
  return EncodeBoxHeader(padding_size, kPaddingBoxType, writer);
}

absl::Status EncodeSerializedSuperBox(absl::Cord payload,
                                      riegeli::BackwardWriter* writer) {
  return WriteRaw(std::move(payload), writer);
}

absl::Status EncodeContentBox(uint32_t tbox, absl::Cord payload,
                              riegeli::BackwardWriter* writer) {
  size_t payload_size = payload.size();
  ABSL_RETURN_IF_ERROR(WriteRaw(std::move(payload), writer));
  return EncodeBoxHeader(payload_size, tbox, writer);
}

absl::Status EncodeDescriptionBox(credentio::Uuid type_uuid,
                                  DescriptionBoxOptions options,
                                  riegeli::BackwardWriter* writer) {
  uint8_t toggles = 0;
  const riegeli::Position pos_before = writer->pos();
  if (options.private_content.has_value()) {
    toggles |= kDescriptionTogglePrivatePresent;
    ABSL_RETURN_IF_ERROR(WriteRaw(*std::move(options.private_content), writer));
  }
  if (options.label.has_value()) {
    if (options.requestable_iff_label) {
      toggles |= kDescriptionToggleRequestable;
    }
    toggles |= kDescriptionToggleLabelPresent;
    ABSL_RETURN_IF_ERROR(WriteNulTerminated(*std::move(options.label), writer));
  }
  ABSL_RETURN_IF_ERROR(WriteInteger(toggles, writer));
  ABSL_RETURN_IF_ERROR(WriteRaw(absl::Cord(type_uuid.ToProtoBytes()), writer));
  return EncodeBoxHeader(writer->pos() - pos_before, kDescriptionBoxType,
                         writer);
}

absl::Status EncodeBoxHeader(riegeli::Position payload_length, uint32_t tbox,
                             riegeli::BackwardWriter* writer) {
  // Minimum box length is payload + mandatory header fields.
  constexpr size_t kMandatoryHeaderLength =
      2 * sizeof(uint32_t);  // LBox and TBox
  if (payload_length > std::numeric_limits<size_t>::max() -
                           kMandatoryHeaderLength - sizeof(uint64_t)) {
    return absl::OutOfRangeError("maximum box size exceeded");
  }
  size_t box_length = payload_length + kMandatoryHeaderLength;
  uint32_t lbox;
  if (box_length > std::numeric_limits<uint32_t>::max()) {
    uint64_t xlbox = box_length + sizeof(uint64_t);
    ABSL_RETURN_IF_ERROR(WriteInteger(xlbox, writer));
    lbox = 1;
  } else {
    lbox = box_length;
  }
  ABSL_RETURN_IF_ERROR(WriteInteger(tbox, writer));
  return WriteInteger(lbox, writer);
}

}  // namespace jumbf
