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

#include <string>
#include <utility>
#include <variant>

#include "absl/base/nullability.h"
#include "absl/log/die_if_null.h"
#include "absl/status/status.h"
#include "absl/status/status_macros.h"
#include "absl/status/statusor.h"
#include "absl/strings/match.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_split.h"
#include "absl/strings/string_view.h"
#include "absl/strings/strip.h"
#include "jumbf/box.h"

namespace jumbf {
namespace {

absl::string_view GetLabel(const SuperBox& box) {
  if (box.description.label.has_value()) {
    return *box.description.label;
  }
  return "";
}

// Returns the first child superbox with the given label, or error if not
// found.
absl::StatusOr<const SuperBox*> GetChild(const SuperBox* box,
                                         absl::string_view label) {
  if (label == "." || label == "..") {
    return absl::InvalidArgumentError("Unsupported path component");
  }
  for (const ContentBox& content : box->contents) {
    if (std::holds_alternative<SuperBox>(content.payload)) {
      const SuperBox& child = std::get<SuperBox>(content.payload);
      if (GetLabel(child) == label) {
        return &child;
      }
    }
  }
  return absl::NotFoundError("");
}

}  // namespace

UriResolver UriResolver::WithSingleRootChild(const SuperBox* root_child) {
  return UriResolver(root_child, absl::StrCat("/", GetLabel(*root_child), "/"));
}

UriResolver::UriResolver(const SuperBox* absl_nonnull root_box,
                         std::string root_path)
    : root_box_(*ABSL_DIE_IF_NULL(root_box)),
      root_path_(std::move(root_path)) {}

absl::StatusOr<std::string> UriResolver::GetAbsolutePathFromUri(
    absl::string_view uri, absl::string_view current_path) {
  if (!absl::ConsumePrefix(&uri, "self#jumbf=")) {
    return absl::InvalidArgumentError("self#jumbf= prefix required");
  }
  return GetAbsolutePath(uri, current_path);
}

std::string UriResolver::GetAbsolutePath(absl::string_view path,
                                         absl::string_view current_path) {
  if (absl::StartsWith(path, "/")) {
    // Absolute path.
    return std::string(path);
  }
  // Relative path.
  return absl::StrCat(current_path, "/", path);
}

absl::StatusOr<const SuperBox*> UriResolver::ResolvePath(
    absl::string_view absolute_path) const {
  const SuperBox* box = nullptr;
  if (!absl::ConsumePrefix(&absolute_path, root_path_)) {
    return absl::NotFoundError("");
  }
  box = &root_box_;
  for (absl::string_view label : absl::StrSplit(absolute_path, '/')) {
    ABSL_ASSIGN_OR_RETURN(auto child_box, GetChild(box, label));
    box = std::move(child_box);
  }
  return box;
}

}  // namespace jumbf
