// 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 "formats/pdf/extractor.h"

#include <optional>
#include <string>
#include <utility>
#include <variant>
#include <vector>

#include "absl/algorithm/container.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "constants/labels.h"
#include "formats/byte_range.h"
#include "formats/pdf/constants.h"
#include "formats/pdf/manifest_store_merger.h"
#include "formats/pdf/objects.h"
#include "formats/pdf/reader.h"
#include "jumbf/utils.h"
#if defined(__GNUC__) || defined(__clang__)
#include <cxxabi.h>  // IWYU pragma: keep

#include <cstdlib>
#include <memory>
#endif
#include "absl/status/status_macros.h"
#include "riegeli/bytes/reader.h"

namespace credentio {
namespace {

std::string Demangle(const char* mangled) {
#if defined(__GNUC__) || defined(__clang__)
  int status = 0;
  std::unique_ptr<char, void (*)(void*)> res{
      abi::__cxa_demangle(mangled, nullptr, nullptr, &status), std::free};
  return (status == 0) ? res.get() : mangled;
#else
  return mangled;
#endif
}

struct C2paManifestStore {
  ByteRange location;
  std::string content;
};

// Checks if `file_spec_dict` is a file spec dictionary for an embedded C2PA
// file stream.
absl::StatusOr<bool> IsC2paManifestFileSpec(
    const Object::Dictionary& file_spec_dict) {
  const auto af_relationship = FindObjectInDictionary<Object::Name>(
      file_spec_dict, kPdfAfRelationshipKey);
  if (!af_relationship.ok()) {
    if (absl::IsNotFound(af_relationship.status())) {
      return false;
    }
    return af_relationship.status();
  }
  return af_relationship->value == kPdfC2paManifestAfRelationship;
}

// Checks that the embedded file stream subtype is as expected.
absl::StatusOr<bool> IsC2paManifestSubtype(
    const IndirectObject& embedded_file_obj) {
  if (!embedded_file_obj.stream_dictionary.has_value()) {
    return false;
  }
  const auto subtype = FindObjectInDictionary<Object::Name>(
      *embedded_file_obj.stream_dictionary, kPdfSubtypeKey);
  if (!subtype.ok()) {
    // Optionally check the subtype if it exists as it is only required in C2PA
    // v2.2 onward.
    if (absl::IsNotFound(subtype.status())) {
      return true;
    }
    return subtype.status();
  }
  return subtype->value == kPdfC2paManifestMimeType;
}

// Gets the indirect reference to the embedded file stream from the file spec
// dictionary under the '/EF/F' key.
absl::StatusOr<Object::IndirectReference> GetEmbeddedFileRef(
    const Object::Dictionary& file_spec_dict) {
  ABSL_ASSIGN_OR_RETURN(
      const auto ef_dict,
      FindObjectInDictionary<Object::Dictionary>(file_spec_dict, kPdfEfKey));

  return FindObjectInDictionary<Object::IndirectReference>(ef_dict, kPdfFKey);
}

// Gets the array of embedded file name and indirect reference pairs from the
// catalog dictionary under the '/Names/EmbeddedFiles/Names' key.
absl::StatusOr<Object::Array> GetEmbeddedFilesNameTreeArray(
    const Object::Dictionary& catalog_dict, PdfReader& reader) {
  if (auto it = catalog_dict.entries.find(kPdfNamesKey);
      it != catalog_dict.entries.end()) {
    // /Catalog/Names
    Object::Dictionary names_dict;
    if (std::holds_alternative<Object::IndirectReference>(it->second.value)) {
      const auto& names_ref =
          std::get<Object::IndirectReference>(it->second.value);
      ABSL_ASSIGN_OR_RETURN(const auto names_obj,
                            reader.GetObject(names_ref.object_number,
                                             names_ref.generation_number));
      ABSL_ASSIGN_OR_RETURN(names_dict,
                            Object::As<Object::Dictionary>(names_obj.object));
    } else if (std::holds_alternative<Object::Dictionary>(it->second.value)) {
      names_dict = std::get<Object::Dictionary>(it->second.value);
    } else {
      return absl::InvalidArgumentError(
          absl::StrCat("Unexpected object type found. Expected "
                       "IndirectReference or Dictionary, but got ",
                       Demangle(typeid(it->second.value).name())));
    }
    // /Catalog/Names/EmbeddedFiles
    auto name_tree_it = names_dict.entries.find(kPdfEmbeddedFilesKey);
    if (name_tree_it == names_dict.entries.end()) {
      return absl::NotFoundError("No '/EmbeddedFiles' dictionary found.");
    }
    Object::Dictionary name_tree_dict;
    if (std::holds_alternative<Object::IndirectReference>(
            name_tree_it->second.value)) {
      const auto& name_tree_ref =
          std::get<Object::IndirectReference>(name_tree_it->second.value);
      ABSL_ASSIGN_OR_RETURN(const auto name_tree_obj,
                            reader.GetObject(name_tree_ref.object_number,
                                             name_tree_ref.generation_number));
      ABSL_ASSIGN_OR_RETURN(
          name_tree_dict, Object::As<Object::Dictionary>(name_tree_obj.object));
    } else if (std::holds_alternative<Object::Dictionary>(
                   name_tree_it->second.value)) {
      name_tree_dict = std::get<Object::Dictionary>(name_tree_it->second.value);
    } else {
      return absl::InvalidArgumentError(
          absl::StrCat("Unexpected object type found. Expected "
                       "IndirectReference or Dictionary, but got ",
                       Demangle(typeid(name_tree_it->second.value).name())));
    }
    // /Catalog/Names/EmbeddedFiles/Names
    return FindObjectInDictionary<Object::Array>(name_tree_dict, kPdfNamesKey);
  } else {
    return absl::NotFoundError(
        "No '/Names' dictionary found in the document catalog.");
  }
}

absl::StatusOr<C2paManifestStore> ExtractManifestStoreInternal(
    riegeli::Reader& input) {
  ABSL_ASSIGN_OR_RETURN(auto reader, PdfReader::Create(&input));

  // Locate the active manifest store in the file trailer dictionary.
  const Object::Dictionary& file_trailer_dict =
      reader->file_trailer_dictionary();

  ABSL_ASSIGN_OR_RETURN(const auto root_ref,
                        FindObjectInDictionary<Object::IndirectReference>(
                            file_trailer_dict, kPdfRootKey));

  ABSL_ASSIGN_OR_RETURN(
      auto root_obj,
      reader->GetObject(root_ref.object_number, root_ref.generation_number));
  ABSL_ASSIGN_OR_RETURN(auto catalog_dict,
                        Object::As<Object::Dictionary>(root_obj.object));

  const auto& file_spec_array =
      FindObjectInDictionary<Object::Array>(catalog_dict, kPdfAfKey);
  if (absl::IsNotFound(file_spec_array.status())) {
    // Early return if the document catalog dictionary does not contain the
    // required '/AF' entry for C2PA manifest extraction.
    return absl::NotFoundError("No manifest store found.");
  }
  ABSL_RETURN_IF_ERROR(file_spec_array.status());

  ABSL_ASSIGN_OR_RETURN(auto name_tree_array,
                        GetEmbeddedFilesNameTreeArray(catalog_dict, *reader));

  std::vector<C2paManifestStore> found_manifest_stores;

  for (const auto& file_spec_obj : file_spec_array->objects) {
    Object::Dictionary file_spec_dict;
    Object::IndirectReference file_spec_ref;
    if (std::holds_alternative<Object::IndirectReference>(
            file_spec_obj.value)) {
      // C2PA manifest file spec is expected to be referenced indirectly from
      // the '/AF' array.
      file_spec_ref = std::get<Object::IndirectReference>(file_spec_obj.value);
      ABSL_ASSIGN_OR_RETURN(auto file_spec_dict_obj,
                            reader->GetObject(file_spec_ref.object_number,
                                              file_spec_ref.generation_number));
      ABSL_ASSIGN_OR_RETURN(file_spec_dict, Object::As<Object::Dictionary>(
                                                file_spec_dict_obj.object));
    } else {
      // Not an indirect reference, continue searching.
      continue;
    }

    ABSL_ASSIGN_OR_RETURN(auto is_c2pa_manifest_file_spec,
                          IsC2paManifestFileSpec(file_spec_dict));
    if (!is_c2pa_manifest_file_spec) {
      continue;
    }

    ABSL_ASSIGN_OR_RETURN(auto embedded_file_ref,
                          GetEmbeddedFileRef(file_spec_dict));

    // The C2PA manifest file spec object should also be referenced from the
    // '/EmbeddedFiles' NameTree.
    if (absl::c_any_of(name_tree_array.objects, [&](const auto& name_tree_obj) {
          return std::holds_alternative<Object::IndirectReference>(
                     name_tree_obj.value) &&
                 std::get<Object::IndirectReference>(name_tree_obj.value)
                         .object_number == file_spec_ref.object_number &&
                 std::get<Object::IndirectReference>(name_tree_obj.value)
                         .generation_number == file_spec_ref.generation_number;
        })) {
      // The embedded file reference was found in the NameTree.
      // Proceed with extraction.
    } else {
      // The embedded file reference was NOT found in the NameTree.
      continue;
    }

    ABSL_ASSIGN_OR_RETURN(
        auto embedded_file_obj,
        reader->GetObject(embedded_file_ref.object_number,
                          embedded_file_ref.generation_number));
    ABSL_ASSIGN_OR_RETURN(auto is_c2pa_manifest_subtype,
                          IsC2paManifestSubtype(embedded_file_obj));
    if (!is_c2pa_manifest_subtype) {
      continue;
    }
    ABSL_ASSIGN_OR_RETURN(auto embedded_file_stream,
                          Object::As<Object::Stream>(embedded_file_obj.object));
    ABSL_ASSIGN_OR_RETURN(
        auto embedded_file_offset,
        reader->GetObjectOffset(embedded_file_ref.object_number,
                                embedded_file_ref.generation_number));
    found_manifest_stores.push_back(C2paManifestStore{
        .location = {.offset = embedded_file_offset,
                     .length = input.pos() - embedded_file_offset},
        .content = embedded_file_stream.raw_value});
  }

  if (found_manifest_stores.empty()) {
    return absl::NotFoundError("No manifest store found.");
  }

  std::vector<absl::string_view> store_contents;
  store_contents.reserve(found_manifest_stores.size());
  for (const auto& store : found_manifest_stores) {
    store_contents.push_back(store.content);
  }
  ABSL_ASSIGN_OR_RETURN(std::string merged,
                        MergeManifestStores(store_contents));

  return C2paManifestStore{
      .location = found_manifest_stores.back().location,
      .content = std::move(merged),
  };
}
}  // namespace

absl::StatusOr<std::string> PdfExtractor::ExtractManifestStore(
    riegeli::Reader& input) const {
  ABSL_ASSIGN_OR_RETURN(auto c2pa_manifest_store,
                        ExtractManifestStoreInternal(input));
  return c2pa_manifest_store.content;
}

absl::StatusOr<std::optional<ByteRange>>
PdfExtractor::ExtractManifestStoreLocation(riegeli::Reader& input,
                                           ExtractOptions options) const {
  auto c2pa_manifest_store = ExtractManifestStoreInternal(input);

  // Extraction failed but C2PA is required, return an error.
  if (!c2pa_manifest_store.ok() && options.requires_c2pa) {
    return absl::NotFoundError("No manifest store found");
  }
  // Extraction failed but C2PA is not required, return nullopt.
  if (!c2pa_manifest_store.ok() && !options.requires_c2pa) {
    return std::nullopt;
  }
  // Extraction succeeded, return the location.
  return c2pa_manifest_store->location;
}

bool PdfExtractor::MightBeC2paManifestStore(absl::string_view payload) const {
  return jumbf::HasDescriptionBoxMatching(payload, kManifestStoreUuid,
                                          kMinimumJumbfDescriptionToggles,
                                          kManifestStoreLabel)
      .value_or(false);
}
}  // namespace credentio
