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

#include <cstdint>
#include <memory>
#include <optional>
#include <string>
#include <utility>

#include "absl/base/nullability.h"
#include "absl/container/btree_map.h"
#include "absl/container/btree_set.h"
#include "absl/container/flat_hash_set.h"
#include "absl/memory/memory.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/substitute.h"
#include "formats/pdf/object_reader.h"
#include "formats/pdf/objects.h"
#include "re2/re2.h"
#include "riegeli/bytes/reader.h"

namespace credentio {
namespace {

// Matches the cross-reference table offset in the trailer. See ISO 32000-2
// Section 7.5.5
static constexpr LazyRE2 kXrefOffsetPattern = {R"(startxref\s(\d+)\s%%EOF)"};

// Matches a single cross-reference entry in the cross-reference table. See ISO
// 32000-2 Section 7.5.4
static constexpr LazyRE2 kXrefEntryPattern = {
    R"(^(\d{10}) (\d{5}) ([nf])(?: \r| \n|\r\n))"};

// Reads the first cross-reference table offset from the file trailer.
absl::StatusOr<uint64_t> GetFirstXrefTableOffset(riegeli::Reader& input) {
  // Scan the last 30 bytes for the cross-reference table offset. This allows
  // for the "startxref" keyword and an offset value large enough for a
  // multi-terabyte file.
  if (!input.Seek(input.Size().value_or(30) - 30)) {
    return input.StatusOrAnnotate(
        absl::DataLossError("Failed to seek to offset"));
  }

  std::string buffer;
  if (!input.Read(30, buffer)) {
    return input.StatusOrAnnotate(absl::DataLossError("Failed to read buffer"));
  }
  uint64_t offset;
  if (!RE2::PartialMatch(buffer, *kXrefOffsetPattern, &offset)) {
    return absl::InvalidArgumentError(
        absl::StrCat("Failed to find cross-reference table offset in the "
                     "following payload: ",
                     buffer));
  }
  return offset;
}

// Reads the offset to the next cross-reference table from the file trailer.
// Returns `std::nullopt` if the file trailer dictionary does not contain a
// "Prev" entry.
absl::StatusOr<std::optional<uint64_t>> GetPrevXrefTableOffset(
    const Object::Dictionary& file_trailer_dict) {
  if (const auto it = file_trailer_dict.entries.find("Prev");
      it != file_trailer_dict.entries.end()) {
    ABSL_ASSIGN_OR_RETURN(const auto prev_xref_offset,
                          Object::As<Object::Integer>(it->second));
    return prev_xref_offset.value;
  }
  return std::nullopt;
}

// Reads the standard cross-reference table and the file trailer from the input
// stream at the given offset.
absl::Status ReadXrefTableAndTrailer(
    riegeli::Reader& input, uint64_t xref_offset,
    absl::btree_map<Object::IndirectReference, uint64_t>& xref_table,
    absl::btree_set<Object::IndirectReference>& free_entries,
    Object::Dictionary& file_trailer_dict) {
  if (!input.Seek(xref_offset)) {
    return input.StatusOrAnnotate(
        absl::DataLossError("Failed to seek to offset"));
  }

  std::string buffer;
  if (!input.Read(4, buffer)) {
    return input.StatusOrAnnotate(absl::DataLossError("Failed to read buffer"));
  }
  if (buffer != "xref") {
    return absl::InvalidArgumentError(
        absl::StrCat("Malformed cross-reference table. Expected 'xref' but got "
                     "'",
                     buffer, "'"));
  }
  while (true) {
    ABSL_RETURN_IF_ERROR(SkipOverWhiteSpaces(input));
    if (!input.Read(7, buffer)) {
      return input.StatusOrAnnotate(
          absl::DataLossError("Failed to read buffer"));
    }
    if (buffer == "trailer") {
      break;
    }
    if (!input.Seek(input.pos() - 7)) {
      return input.StatusOrAnnotate(
          absl::DataLossError("Failed to seek to offset"));
    }

    Object int_obj;
    ABSL_RETURN_IF_ERROR(ReadObject(input, input.pos(), int_obj));
    ABSL_ASSIGN_OR_RETURN(const auto obj_num,
                          Object::As<Object::Integer>(int_obj));

    ABSL_RETURN_IF_ERROR(ReadObject(input, input.pos(), int_obj));
    ABSL_ASSIGN_OR_RETURN(const auto obj_count,
                          Object::As<Object::Integer>(int_obj));

    ABSL_RETURN_IF_ERROR(SkipOverWhiteSpaces(input));

    for (uint32_t i = 0; i < obj_count.value; ++i) {
      // Each cross-reference entry is expected to be exactly 20 bytes long.
      if (!input.Read(20, buffer)) {
        return input.StatusOrAnnotate(
            absl::DataLossError("Failed to read buffer"));
      }
      uint64_t obj_offset;
      uint32_t gen_num;
      std::string type;
      if (RE2::PartialMatch(buffer, *kXrefEntryPattern, &obj_offset, &gen_num,
                            &type)) {
        auto xref_entry_key = Object::IndirectReference{
            .object_number = static_cast<uint32_t>(obj_num.value + i),
            .generation_number = gen_num};
        if (type == "n") {  // 'n' represents an in-use entry.
          xref_table.insert({xref_entry_key, obj_offset});
        } else {  // 'f' represents a free entry.
          free_entries.insert(xref_entry_key);
        }
      } else {
        return absl::InvalidArgumentError(
            absl::StrCat("Failed to parse cross-reference table entry. Invalid "
                         "value: ",
                         buffer));
      }
    }
  }
  Object dict_obj;
  ABSL_RETURN_IF_ERROR(ReadObject(input, input.pos(), dict_obj));
  ABSL_ASSIGN_OR_RETURN(file_trailer_dict,
                        Object::As<Object::Dictionary>(dict_obj));

  return absl::OkStatus();
}
}  // namespace

absl::StatusOr<std::unique_ptr<PdfReader>> PdfReader::Create(
    riegeli::Reader* absl_nonnull input) {
  if (input == nullptr) {
    return absl::InvalidArgumentError("input cannot be null");
  }
  absl::flat_hash_set<uint64_t> xref_offsets_visited;
  ABSL_ASSIGN_OR_RETURN(uint64_t xref_offset, GetFirstXrefTableOffset(*input));
  xref_offsets_visited.insert(xref_offset);

  absl::btree_map<Object::IndirectReference, uint64_t> xref_table;
  absl::btree_set<Object::IndirectReference> free_entries;
  Object::Dictionary file_trailer_dict;
  ABSL_RETURN_IF_ERROR(ReadXrefTableAndTrailer(
      *input, xref_offset, xref_table, free_entries, file_trailer_dict));

  ABSL_ASSIGN_OR_RETURN(std::optional<uint64_t> prev_xref_offset,
                        GetPrevXrefTableOffset(file_trailer_dict));
  while (prev_xref_offset.has_value()) {
    if (xref_offsets_visited.contains(*prev_xref_offset)) {
      return absl::InvalidArgumentError(
          "Initialization failed: Circular cross-reference table detected.");
    }
    xref_offsets_visited.insert(*prev_xref_offset);

    absl::btree_map<Object::IndirectReference, uint64_t> prev_xref_table;
    absl::btree_set<Object::IndirectReference> prev_free_entries;
    Object::Dictionary prev_file_trailer_dict;
    ABSL_RETURN_IF_ERROR(
        ReadXrefTableAndTrailer(*input, *prev_xref_offset, prev_xref_table,
                                prev_free_entries, prev_file_trailer_dict));
    ABSL_ASSIGN_OR_RETURN(prev_xref_offset,
                          GetPrevXrefTableOffset(prev_file_trailer_dict));

    xref_table.merge(prev_xref_table);
    if (!prev_xref_table.empty()) {
      return absl::InvalidArgumentError(
          "Initialization failed: Collision detected in cross-reference "
          "table for in-use entries.");
    }
    free_entries.merge(prev_free_entries);
    if (!prev_free_entries.empty()) {
      return absl::InvalidArgumentError(
          "Initialization failed: Collision detected in cross-reference "
          "table for free entries.");
    }
  }
  auto reader = absl::WrapUnique(new PdfReader(input, std::move(xref_table),
                                               std::move(free_entries),
                                               std::move(file_trailer_dict)));
  return reader;
}

bool PdfReader::HasNext() { return current_it_ != xref_table_.end(); }

absl::StatusOr<IndirectObject> PdfReader::Next() {
  if (!HasNext()) {
    return absl::OutOfRangeError("No more objects to read.");
  }
  IndirectObject obj;
  if (absl::Status status = ReadIndirectObject(
          input_, current_it_->second,
          [this](const Object::IndirectReference& ref) {
            return this->GetObject(ref.object_number, ref.generation_number);
          },
          obj);
      !status.ok()) {
    return status;
  }
  ++current_it_;
  return obj;
}

absl::StatusOr<uint64_t> PdfReader::GetObjectOffset(
    uint32_t object_number, uint32_t generation_number) {
  auto it = xref_table_.find(Object::IndirectReference{
      .object_number = object_number, .generation_number = generation_number});
  if (it == xref_table_.end()) {
    return absl::NotFoundError(absl::Substitute(
        "No offset found for object number: $0, generation number: $1",
        object_number, generation_number));
  }
  return it->second;
}

absl::StatusOr<IndirectObject> PdfReader::GetObject(
    uint32_t object_number, uint32_t generation_number) {
  Object::IndirectReference ref{.object_number = object_number,
                                .generation_number = generation_number};
  if (active_objects_.contains(ref)) {
    return absl::InvalidArgumentError(
        absl::StrCat("Circular reference detected for object: ", object_number,
                     " ", generation_number));
  }

  struct ActiveObjectGuard {
    absl::btree_set<Object::IndirectReference>& active_objects;
    Object::IndirectReference ref;
    ~ActiveObjectGuard() { active_objects.erase(ref); }
  };
  active_objects_.insert(ref);
  ActiveObjectGuard guard{active_objects_, ref};

  ABSL_ASSIGN_OR_RETURN(uint64_t offset,
                        GetObjectOffset(object_number, generation_number));
  IndirectObject obj;
  if (absl::Status status = ReadIndirectObject(
          input_, offset,
          [this](const Object::IndirectReference& ref) {
            return this->GetObject(ref.object_number, ref.generation_number);
          },
          obj);
      !status.ok()) {
    return status;
  }
  return obj;
}

}  // namespace credentio
