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

#include <sys/types.h>

#include <cstdint>
#include <utility>
#include <variant>

#include "absl/functional/overload.h"
#include "absl/status/status.h"
#include "absl/status/status_macros.h"
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include "absl/strings/strip.h"
#include "jumbf/box.h"
#include "jumbf/constants.h"
#include "jumbf/internal/serialization_utils.h"
#include "uuid/uuid.h"

namespace jumbf {

namespace {

// Consumes the header of a JUMBF Box and returns the TBox.
//
// The header is a 4 byte unsigned integer (LBox) followed by a 4 byte unsigned
// integer (TBox). If the first integer is 1, it's followed by a 8 byte unsigned
// integer (XLBox).
absl::StatusOr<uint32_t> ConsumeHeader(absl::string_view* payload) {
  ABSL_ASSIGN_OR_RETURN(auto lbox,
                        jumbf_internal::ConsumeInteger<uint32_t>(payload));
  ABSL_ASSIGN_OR_RETURN(auto tbox,
                        jumbf_internal::ConsumeInteger<uint32_t>(payload));
  if (lbox == 1) {
    ABSL_RETURN_IF_ERROR(
        jumbf_internal::ConsumeBytes(payload, sizeof(uint64_t)).status());
  }
  return tbox;
}

}  // namespace

absl::StatusOr<absl::string_view> StripBoxHeaders(absl::string_view raw_bytes) {
  ABSL_ASSIGN_OR_RETURN(auto lbox,
                        jumbf_internal::ConsumeInteger<uint32_t>(&raw_bytes));
  ABSL_RETURN_IF_ERROR(
      jumbf_internal::ConsumeBytes(&raw_bytes, sizeof(uint32_t)).status());
  if (lbox == 1) {
    ABSL_RETURN_IF_ERROR(
        jumbf_internal::ConsumeBytes(&raw_bytes, sizeof(uint64_t)).status());
  }
  return raw_bytes;
}

absl::StatusOr<bool> HasDescriptionBoxMatching(absl::string_view raw_bytes,
                                               const credentio::Uuid& uuid,
                                               uint8_t toggles_mask,
                                               absl::string_view label) {
  // Super Box Header
  ABSL_ASSIGN_OR_RETURN(auto super_tbox, ConsumeHeader(&raw_bytes));
  if (super_tbox != kSuperBoxType) {
    return false;
  }

  // Description Box Header
  ABSL_ASSIGN_OR_RETURN(auto description_tbox, ConsumeHeader(&raw_bytes));
  if (description_tbox != kDescriptionBoxType) {
    return false;
  }

  // Description Box UUID
  if (raw_bytes.size() < 16) {
    return absl::OutOfRangeError("Description Box UUID is missing.");
  }
  ABSL_ASSIGN_OR_RETURN(auto description_uuid, credentio::Uuid::FromProtoBytes(
                                                   raw_bytes.substr(0, 16)));
  raw_bytes.remove_prefix(16);
  if (std::move(description_uuid) != uuid) {
    return false;
  }

  // Description Box Toggles
  ABSL_ASSIGN_OR_RETURN(auto toggles,
                        jumbf_internal::ConsumeInteger<uint8_t>(&raw_bytes));
  if ((toggles & toggles_mask) != toggles_mask) {
    return false;
  }

  // Expected Label
  if (!absl::ConsumePrefix(&raw_bytes, label)) {
    return false;
  }

  // Ensure the next character is the null terminator
  ABSL_ASSIGN_OR_RETURN(auto next_byte,
                        jumbf_internal::ConsumeInteger<uint8_t>(&raw_bytes));
  return next_byte == 0x00;
}

int GetContextBoxSize(const ContentBox& box) {
  int content_size = 0;
  std::visit(
      absl::Overload{
          [&](const UnknownBox& arg) { content_size = arg.payload.size(); },
          [&](const CborBox& arg) { content_size = arg.payload.size(); },
          [&](const SerializedSuperbox& arg) {
            content_size = arg.serialized.size();
          },
          [&](const SuperBox& arg) { content_size = arg.raw_bytes.size(); },
          [&](const EmbeddedFileDescriptionBox& arg) {
            // See section B.6.2
            // Always include a byte for toggles
            content_size = 1;
            // Add media type size + 1 for null terminator
            content_size += arg.media_type.size() + 1;
            if (arg.file_name.has_value()) {
              // Add file name size + 1 for null terminator
              content_size += arg.file_name->size() + 1;
            }
          },
          [&](const BinaryDataBox& arg) { content_size = arg.payload.size(); },
          [&](const C2paSaltBox& arg) { content_size = arg.salt.size(); },
          [&](const JsonBox& arg) { content_size = arg.payload.size(); },
          [&](const UuidBox& arg) { content_size = arg.payload.size(); },
      },
      box.payload);
  return content_size;
}

}  // namespace jumbf
