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

#include <algorithm>
#include <optional>
#include <utility>
#include <vector>

#include "absl/status/status.h"
#include "absl/status/status_macros.h"
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include "jumbf/box.h"
#include "jumbf/constants.h"
#include "jumbf/internal/consume_box.h"
#include "jumbf/internal/intermediate.h"
#include "jumbf/internal/parse_embedded_file_description_box.h"
#include "jumbf/internal/parse_super_box.h"

namespace jumbf {

using ::jumbf_internal::ConsumeBox;
using ::jumbf_internal::IntermediateBox;
using ::jumbf_internal::IntermediateDescriptionBox;
using ::jumbf_internal::ParseEmbeddedFileDescriptionBox;

namespace {

absl::StatusOr<ContentBox> ParseContentBox(const IntermediateBox& unwrapped_box,
                                           int recursion_limit);

absl::StatusOr<SuperBox> ParseSuperBox(
    const IntermediateBox& unwrapped_super_box, int recursion_limit);

absl::StatusOr<DescriptionBox> FinalizeDescriptionBox(
    const IntermediateDescriptionBox& intermediate_box, int recursion_limit) {
  std::vector<ContentBox> private_contents;
  if (intermediate_box.private_box.has_value()) {
    const IntermediateBox& private_box = *intermediate_box.private_box;
    absl::string_view private_content_view = private_box.payload;
    if (private_box.type == kPrivateContentBoxType) {
      // Special private box type, repeated list of arbitrary boxes.
      while (!private_content_view.empty()) {
        ABSL_ASSIGN_OR_RETURN(
            auto unwrapped_private_element,
            ConsumeBox(&private_content_view, /*allow_implicit_length=*/false),
            _.SetPrepend() << "could not unwrap private content box for index "
                           << private_contents.size() << ": ");

        ABSL_ASSIGN_OR_RETURN(
            auto private_element,
            ParseContentBox(unwrapped_private_element, recursion_limit),
            _.SetPrepend() << "could not parse private content box for index "
                           << private_contents.size() << ": ");

        private_contents.push_back(std::move(private_element));
      }
    } else {
      ABSL_ASSIGN_OR_RETURN(auto private_element,
                            ParseContentBox(private_box, recursion_limit));
      private_contents.push_back(std::move(private_element));
    }
  }

  return DescriptionBox{
      .type_uuid = intermediate_box.type_uuid,
      .requestable = intermediate_box.requestable,
      .label = intermediate_box.label,
      .id = intermediate_box.id,
      .unvalidated_hash = intermediate_box.hash,
      .private_content = std::move(private_contents),
  };
}

absl::StatusOr<ContentBox> ParseContentBox(const IntermediateBox& unwrapped_box,
                                           int recursion_limit) {
  if (recursion_limit < 0) {
    // All negative values mean "no recursion limit". Pick -1 to avoid worries
    // about underflow when we subtract from it.
    recursion_limit = -1;
  }
  switch (unwrapped_box.type) {
    case kCborBoxType:
      return ContentBox{
          .raw_bytes = unwrapped_box.serialized,
          .payload =
              CborBox{
                  .payload = unwrapped_box.payload,
              },
      };
    case kSuperBoxType: {
      if (recursion_limit == 0) {
        return ContentBox{
            .raw_bytes = unwrapped_box.serialized,
            .payload =
                SerializedSuperbox{
                    .serialized = unwrapped_box.serialized,
                },
        };
      } else {
        ABSL_ASSIGN_OR_RETURN(
            auto super_box,
            ParseSuperBox(unwrapped_box, std::max(recursion_limit - 1, -1)));
        return ContentBox{
            .raw_bytes = unwrapped_box.serialized,
            .payload = std::move(super_box),
        };
      }
      break;
    }
    case kEmbeddedFileDescriptionBoxType: {
      ABSL_ASSIGN_OR_RETURN(auto efdb,
                            ParseEmbeddedFileDescriptionBox(unwrapped_box));
      return ContentBox{
          .raw_bytes = unwrapped_box.serialized,
          .payload = std::move(efdb),
      };
    }
    case kBinaryDataBoxType:
      return ContentBox{
          .raw_bytes = unwrapped_box.serialized,
          .payload = BinaryDataBox{.payload = unwrapped_box.payload},
      };
    case kC2paSaltBoxType:
      return ContentBox{
          .raw_bytes = unwrapped_box.serialized,
          .payload = C2paSaltBox{.salt = unwrapped_box.payload},
      };
    case kJsonBoxType:
      return ContentBox{
          .raw_bytes = unwrapped_box.serialized,
          .payload = JsonBox{.payload = unwrapped_box.payload},
      };
    case kUuidBoxType:
      return ContentBox{
          .raw_bytes = unwrapped_box.serialized,
          .payload = UuidBox{.payload = unwrapped_box.payload},
      };
    default:
      return ContentBox{
          .raw_bytes = unwrapped_box.serialized,
          .payload =
              UnknownBox{
                  .type = unwrapped_box.type,
                  .payload = unwrapped_box.payload,
              },
      };
  }
}

absl::StatusOr<SuperBox> ParseSuperBox(
    const IntermediateBox& unwrapped_super_box, int recursion_limit) {
  ABSL_ASSIGN_OR_RETURN(auto intermediate_super_box,
                        jumbf_internal::ParseSuperBox(unwrapped_super_box));

  std::vector<ContentBox> contents;
  contents.reserve(intermediate_super_box.content.size());
  for (int i = 0; i < intermediate_super_box.content.size(); ++i) {
    ABSL_ASSIGN_OR_RETURN(
        auto content,
        ParseContentBox(intermediate_super_box.content[i], recursion_limit),
        _.SetPrepend() << "could not parse content box for index " << i
                       << ": ");
    contents.push_back(std::move(content));
  }

  ABSL_ASSIGN_OR_RETURN(
      auto description,
      FinalizeDescriptionBox(intermediate_super_box.description,
                             recursion_limit),
      _.SetPrepend() << "could not finalize description box: ");

  return SuperBox{
      .description = std::move(description),
      .contents = std::move(contents),
      .raw_bytes = intermediate_super_box.serialized,
  };
}

}  // namespace

absl::StatusOr<SuperBox> ConsumeSuperBox(
    absl::string_view* serialized_super_box, int recursion_limit,
    bool allow_implicit_length) {
  absl::string_view temp_serialized_super_box = *serialized_super_box;
  ABSL_ASSIGN_OR_RETURN(
      auto unwrapped_super_box,
      ConsumeBox(&temp_serialized_super_box, allow_implicit_length),
      _.SetPrepend() << "cannot unwrap super box: ");
  ABSL_ASSIGN_OR_RETURN(auto result,
                        ParseSuperBox(unwrapped_super_box, recursion_limit));
  *serialized_super_box = temp_serialized_super_box;
  return result;
}

}  // namespace jumbf
