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

#include <cstdint>
#include <utility>

#include "absl/log/log.h"
#include "absl/status/status.h"
#include "absl/status/status_macros.h"
#include "absl/status/statusor.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "jumbf/constants.h"
#include "jumbf/internal/consume_box.h"
#include "jumbf/internal/intermediate.h"
#include "jumbf/internal/serialization_utils.h"
#include "uuid/uuid.h"

namespace jumbf_internal {

absl::StatusOr<IntermediateDescriptionBox> ParseDescriptionBox(
    const IntermediateBox& unwrapped_box) {
  if (unwrapped_box.type != jumbf::kDescriptionBoxType) {
    return absl::InvalidArgumentError(
        absl::StrCat("box is not a description box; got type 0x",
                     absl::Hex(unwrapped_box.type), " need 0x",
                     absl::Hex(jumbf::kDescriptionBoxType), " ('jumd')"));
  }
  IntermediateDescriptionBox description_box;

  absl::string_view content = unwrapped_box.payload;
  ABSL_ASSIGN_OR_RETURN(auto uuid_str, ConsumeBytes(&content, 16));
  ABSL_ASSIGN_OR_RETURN(auto type_uuid,
                        credentio::Uuid::FromProtoBytes(std::move(uuid_str)));
  description_box.type_uuid = std::move(type_uuid);

  ABSL_ASSIGN_OR_RETURN(auto toggles, ConsumeInteger<uint8_t>(&content),
                        _.SetPrepend() << "cannot read toggles: ");

  description_box.requestable = toggles & jumbf::kDescriptionToggleRequestable;

  if (toggles & jumbf::kDescriptionToggleLabelPresent) {
    ABSL_ASSIGN_OR_RETURN(description_box.label,
                          ConsumeNullTerminated(&content),
                          _.SetPrepend() << "cannot read label: ");
  } else {
    if (description_box.requestable) {
      return absl::InvalidArgumentError(
          R"(requestable bit is set, but box does not have a label; if a box is requestable the label is required)");
    }
  }

  if (toggles & jumbf::kDescriptionToggleIdPresent) {
    ABSL_ASSIGN_OR_RETURN(description_box.id,
                          ConsumeInteger<uint32_t>(&content),
                          _.SetPrepend() << "cannot read id: ");
  }

  if (toggles & jumbf::kDescriptionToggleHashPresent) {
    ABSL_ASSIGN_OR_RETURN(description_box.hash, ConsumeBytes(&content, 32),
                          _.SetPrepend() << "cannot read hash: ");
  }

  if (toggles & jumbf::kDescriptionTogglePrivatePresent) {
    ABSL_ASSIGN_OR_RETURN(description_box.private_box,
                          ConsumeBox(&content, /*allow_implicit_length=*/false),
                          _.SetPrepend() << "cannot read private content: ");
  }

  return description_box;
}

}  // namespace jumbf_internal
