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

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

#include "absl/functional/any_invocable.h"
#include "absl/status/status.h"
#include "absl/status/status_macros.h"
#include "absl/status/statusor.h"
#include "absl/strings/ascii.h"
#include "absl/strings/match.h"
#include "absl/strings/numbers.h"
#include "absl/strings/str_cat.h"
#include "formats/pdf/objects.h"
#include "re2/re2.h"
#include "riegeli/bytes/reader.h"

namespace credentio {
namespace {

constexpr uint64_t kMaxPayloadSize = 1024 * 1024 * 10;        // 10 MiB
constexpr uint64_t kMaxStringTokenLength = 1024 * 1024 * 10;  // 10 MiB
constexpr uint64_t kMaxNameTokenLength = 4096;
constexpr uint64_t kMaxNumberTokenLength = 128;
constexpr int kMaxObjectRecursionDepth = 100;

// PDF White-space characters. See ISO 32000-2 Section 7.2.3 Table 1.
constexpr bool IsPdfWhiteSpace(uint8_t c) {
  return c == 0x00 || c == 0x09 || c == 0x0a || c == 0x0c || c == 0x0d ||
         c == 0x20;
}
// PDF Delimiter characters. See ISO 32000-2 Section 7.2.3 Table 2.
constexpr bool IsPdfDelimiter(uint8_t c) {
  return c == 0x28 || c == 0x29 || c == 0x3c || c == 0x3e || c == 0x5b ||
         c == 0x5d || c == 0x7b || c == 0x7d || c == 0x2f || c == 0x25;
}

static constexpr LazyRE2 kIndirectReferencePattern = {
    R"(^[+-]?(\d+)\s+(\d+)\s+R[^a-zA-Z])"};

// Reads either an integer or a real number from the given input stream at the
// current position.
absl::Status ReadNumber(riegeli::Reader& input, Object& obj) {
  uint8_t token = 0x00;
  std::string buffer;

  while (true) {
    if (buffer.size() >= kMaxNumberTokenLength) {
      return absl::InvalidArgumentError(
          absl::StrCat("Number token exceeds maximum allowed length: ",
                       kMaxNumberTokenLength));
    }
    if (!input.ReadByte(token)) {
      return input.StatusOrAnnotate(
          absl::DataLossError("Failed to read beginning delimiter"));
    }
    // A number can be terminated by any white-space character or delimiter.
    if (IsPdfWhiteSpace(token) || IsPdfDelimiter(token)) {
      if (!input.Seek(input.pos() - 1)) {
        return input.StatusOrAnnotate(
            absl::DataLossError("Failed to seek to offset"));
      }
      break;
    }
    buffer += token;
  }
  if (absl::StrContains(buffer, '.')) {
    obj.value = Object::RealNumber{.raw_value = std::move(buffer)};
  } else {
    int64_t value;
    if (!absl::SimpleAtoi(buffer, &value)) {
      return absl::InvalidArgumentError(
          absl::StrCat("Failed to parse integer. Invalid value: ", buffer));
    }
    obj.value = Object::Integer{.value = std::move(value)};
  }
  return absl::OkStatus();
}

absl::Status ReadBoolean(riegeli::Reader& input, Object& obj) {
  std::string buffer;
  if (!input.Read(5, buffer)) {
    return input.StatusOrAnnotate(absl::DataLossError("Failed to read buffer"));
  }
  if (buffer.substr(0, 4) == "true") {
    obj.value = Object::Boolean{.value = true};
    if (!input.Seek(input.pos() - 1)) {
      return input.StatusOrAnnotate(
          absl::DataLossError("Failed to seek to offset"));
    }
  } else if (buffer == "false") {
    obj.value = Object::Boolean{.value = false};
  } else {
    return absl::InvalidArgumentError(
        absl::StrCat("Failed to parse boolean. Invalid value: ", buffer));
  }
  return absl::OkStatus();
}

absl::Status ReadLiteralString(riegeli::Reader& input, Object& obj) {
  uint8_t token = 0x00;
  std::string buffer;
  int32_t parentheses_count = 1;

  // Consume the beginning delimiter.
  if (!input.ReadByte(token)) {
    return input.StatusOrAnnotate(
        absl::DataLossError("Failed to read beginning delimiter"));
  }
  if (token != '(') {
    return absl::InvalidArgumentError(
        absl::StrCat("Invalid delimiter. Expected '(' but got 0x",
                     absl::Hex(token), " at offset ", input.pos() - 1));
  }

  while (true) {
    if (buffer.size() >= kMaxStringTokenLength) {
      return absl::InvalidArgumentError(
          absl::StrCat("Literal string exceeds maximum allowed length: ",
                       kMaxStringTokenLength));
    }
    if (!input.ReadByte(token)) {
      return input.StatusOrAnnotate(
          absl::DataLossError("Failed to read beginning delimiter"));
    }
    if (token == '(') {
      parentheses_count++;
    }
    if (token == ')' && --parentheses_count == 0) {
      break;
    }
    buffer += token;
  }
  obj.value = Object::LiteralString{.raw_value = std::move(buffer)};
  return absl::OkStatus();
}

absl::Status ReadHexadecimalString(riegeli::Reader& input, Object& obj) {
  uint8_t token = 0x00;
  std::string buffer;

  // Consume the beginning delimiter.
  if (!input.ReadByte(token)) {
    return input.StatusOrAnnotate(
        absl::DataLossError("Failed to read beginning delimiter"));
  }
  if (token != '<') {
    return absl::InvalidArgumentError(
        absl::StrCat("Invalid delimiter. Expected '<' but got 0x",
                     absl::Hex(token), " at offset ", input.pos() - 1));
  }

  while (true) {
    if (buffer.size() >= kMaxStringTokenLength) {
      return absl::InvalidArgumentError(
          absl::StrCat("Hexadecimal string exceeds maximum allowed length: ",
                       kMaxStringTokenLength));
    }
    if (!input.ReadByte(token)) {
      return input.StatusOrAnnotate(
          absl::DataLossError("Failed to read beginning delimiter"));
    }
    if (token == '>') {
      break;
    }
    buffer += token;
  }
  obj.value = Object::HexadecimalString{.raw_value = std::move(buffer)};
  return absl::OkStatus();
}

absl::Status ReadName(riegeli::Reader& input, Object& obj) {
  uint8_t token = 0x00;
  std::string buffer;

  // Consume the beginning delimiter.
  if (!input.ReadByte(token)) {
    return input.StatusOrAnnotate(
        absl::DataLossError("Failed to read beginning delimiter"));
  }
  if (token != '/') {
    return absl::InvalidArgumentError(
        absl::StrCat("Invalid delimiter. Expected '/' but got 0x",
                     absl::Hex(token), " at offset ", input.pos() - 1));
  }

  while (true) {
    if (buffer.size() >= kMaxNameTokenLength) {
      return absl::InvalidArgumentError(absl::StrCat(
          "Name token exceeds maximum allowed length: ", kMaxNameTokenLength));
    }
    if (!input.ReadByte(token)) {
      return input.StatusOrAnnotate(
          absl::DataLossError("Failed to read beginning delimiter"));
    }
    // A name can be terminated by any white-space character or delimiter.
    if (IsPdfWhiteSpace(token) || IsPdfDelimiter(token)) {
      if (!input.Seek(input.pos() - 1)) {
        return input.StatusOrAnnotate(
            absl::DataLossError("Failed to seek to offset"));
      }
      break;
    }
    if (token == '#') {
      std::string hex_str(2, '\0');
      if (!input.Read(2, hex_str)) {
        return input.StatusOrAnnotate(
            absl::DataLossError("Failed to read hex string"));
      }
      if (!absl::ascii_isxdigit(hex_str[0]) ||
          !absl::ascii_isxdigit(hex_str[1])) {
        return absl::InvalidArgumentError("Invalid hex string");
      }
      int hex_val = 0;
      if (!absl::SimpleHexAtoi(hex_str, &hex_val)) {
        return absl::InvalidArgumentError("Invalid hex string");
      }
      token = hex_val;
    }
    buffer += token;
  }
  obj.value = Object::Name{.value = std::move(buffer)};
  return absl::OkStatus();
}

absl::Status ReadArray(riegeli::Reader& input, Object& obj, int depth) {
  uint8_t token = 0x00;
  Object::Array array;

  // Consume the beginning delimiter.
  if (!input.ReadByte(token)) {
    return input.StatusOrAnnotate(
        absl::DataLossError("Failed to read beginning delimiter"));
  }
  if (token != '[') {
    return absl::InvalidArgumentError(
        absl::StrCat("Invalid delimiter. Expected '[' but got '",
                     absl::Hex(token), "' at offset ", input.pos() - 1));
  }

  while (true) {
    ABSL_RETURN_IF_ERROR(SkipOverWhiteSpaces(input));
    if (!input.ReadByte(token)) {
      return input.StatusOrAnnotate(
          absl::DataLossError("Failed to read beginning delimiter"));
    }
    if (token == ']') {
      break;
    }
    Object sub_obj;
    ABSL_RETURN_IF_ERROR(ReadObject(input, input.pos() - 1, sub_obj, depth));
    array.objects.push_back(std::move(sub_obj));
  }
  obj.value = std::move(array);

  return absl::OkStatus();
}

absl::Status ReadNull(riegeli::Reader& input, Object& obj) {
  std::string buffer;
  if (!input.Read(4, buffer)) {
    return input.StatusOrAnnotate(absl::DataLossError("Failed to read buffer"));
  }
  if (buffer == "null") {
    obj.value = Object::Null{};
  } else {
    return absl::InvalidArgumentError(absl::StrCat("Invalid value: ", buffer));
  }
  return absl::OkStatus();
}

absl::Status ReadDictionary(riegeli::Reader& input, Object& obj, int depth) {
  std::string buffer;
  Object::Dictionary dictionary;

  if (!input.Read(2, buffer)) {
    return input.StatusOrAnnotate(absl::DataLossError("Failed to read buffer"));
  }
  if (buffer != "<<") {
    return absl::InvalidArgumentError(absl::StrCat(
        "Invalid delimiter. Expected '<<' but got '", buffer, "'"));
  }

  while (true) {
    ABSL_RETURN_IF_ERROR(SkipOverWhiteSpaces(input));
    if (!input.Read(2, buffer)) {
      return input.StatusOrAnnotate(
          absl::DataLossError("Failed to read buffer"));
    }
    if (buffer == ">>") {
      break;
    }
    if (!input.Seek(input.pos() - 2)) {
      return input.StatusOrAnnotate(
          absl::DataLossError("Failed to seek to offset"));
    }
    Object name_obj;
    ABSL_RETURN_IF_ERROR(ReadName(input, name_obj));
    ABSL_RETURN_IF_ERROR(SkipOverWhiteSpaces(input));
    Object value_obj;
    ABSL_RETURN_IF_ERROR(ReadObject(input, input.pos(), value_obj, depth));
    ABSL_ASSIGN_OR_RETURN(auto name, Object::As<Object::Name>(name_obj));
    dictionary.entries.insert({name.value, std::move(value_obj)});
  }
  obj.value = std::move(dictionary);

  return absl::OkStatus();
}

absl::Status ReadStream(riegeli::Reader& input, int64_t length, Object& obj) {
  std::string buffer;
  Object::Stream stream;

  if (!input.Read(6, buffer)) {
    return input.StatusOrAnnotate(absl::DataLossError("Failed to read buffer"));
  }
  if (buffer != "stream") {
    return absl::InvalidArgumentError(absl::StrCat(
        "Malformed keyword. Expected 'stream' but got '", buffer, "'"));
  }
  if (!input.Read(2, buffer)) {
    return input.StatusOrAnnotate(absl::DataLossError("Failed to read buffer"));
  }
  // The spec requires "stream" keyword to be followed by a CARRIAGE RETURN and
  // a LINE FEED, or just a LINE FEED.
  if (buffer == "\r\n") {  // CARRIAGE RETURN + LINE FEED
    // Do nothing.
  } else if (buffer[0] == '\n') {  // LINE FEED
    // Seek back to the end of the LINE FEED.
    if (!input.Seek(input.pos() - 1)) {
      return input.StatusOrAnnotate(
          absl::DataLossError("Failed to seek to offset"));
    }
  } else {
    return absl::InvalidArgumentError(absl::StrCat(
        "Malformed stream. Expected '\r\n' or '\n' but got '", buffer, "'"));
  }
  if (length > kMaxPayloadSize) {
    return absl::InvalidArgumentError(
        absl::StrCat("Stream length exceeds maximum allowed size: ", length,
                     " > ", kMaxPayloadSize));
  }
  if (!input.Read(length, stream.raw_value)) {
    return input.StatusOrAnnotate(absl::DataLossError("Failed to read buffer"));
  }
  obj.value = std::move(stream);
  // Skip over the end-of-line marker.
  ABSL_RETURN_IF_ERROR(SkipOverWhiteSpaces(input));
  if (!input.Read(9, buffer)) {
    return input.StatusOrAnnotate(absl::DataLossError("Failed to read buffer"));
  }
  if (buffer != "endstream") {
    return absl::InvalidArgumentError(absl::StrCat(
        "Malformed keyword. Expected 'endstream' but got '", buffer, "'"));
  }
  return absl::OkStatus();
}
}  // namespace

absl::Status ReadObject(riegeli::Reader& input, int64_t obj_offset, Object& obj,
                        int depth) {
  if (depth > kMaxObjectRecursionDepth) {
    return absl::InvalidArgumentError("Max nesting depth exceeded.");
  }
  if (!input.Seek(obj_offset)) {
    return input.StatusOrAnnotate(
        absl::DataLossError("Failed to seek to offset"));
  }

  uint8_t token = 0x00;

  ABSL_RETURN_IF_ERROR(SkipOverWhiteSpaces(input));
  if (!input.ReadByte(token)) {
    return input.StatusOrAnnotate(
        absl::DataLossError("Failed to read beginning delimiter"));
  }
  if (!input.Seek(input.pos() - 1)) {
    return input.StatusOrAnnotate(
        absl::DataLossError("Failed to seek to offset"));
  }
  switch (token) {
    case '+':
    case '-':
    case '.':
    case '0':
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9': {  // Numbers or indirect reference
      std::string buffer(20, '\0');
      // Read more bytes to check if this is an indirect reference.
      if (!input.Read(20, buffer)) {
        return input.StatusOrAnnotate(
            absl::DataLossError("Failed to read buffer"));
      }
      if (!input.Seek(input.pos() - 20)) {
        return input.StatusOrAnnotate(
            absl::DataLossError("Failed to seek to offset"));
      }
      if (uint32_t obj_num, gen_num; RE2::PartialMatch(
              buffer, *kIndirectReferencePattern, &obj_num, &gen_num)) {
        obj.value = Object::IndirectReference{.object_number = obj_num,
                                              .generation_number = gen_num};
        auto pos = buffer.find('R');
        // This should never happen.
        if (pos == std::string::npos) {
          return absl::InternalError(
              "Failed to locate keyword 'R' in indirect reference buffer.");
        }
        if (!input.Seek(input.pos() + pos + 1)) {
          return input.StatusOrAnnotate(
              absl::DataLossError("Failed to seek to offset"));
        }
        break;
      }
      ABSL_RETURN_IF_ERROR(ReadNumber(input, obj));
      break;
    }
    case 't':
    case 'f': {  // Boolean
      ABSL_RETURN_IF_ERROR(ReadBoolean(input, obj));
      break;
    }
    case '(': {  // Literal string
      ABSL_RETURN_IF_ERROR(ReadLiteralString(input, obj));
      break;
    }
    case '<': {  // Hexadecimal string or Dictionary
      // Read one more byte to determine the object type.
      std::string buffer(2, '\0');
      if (!input.Read(2, buffer)) {
        return input.StatusOrAnnotate(
            absl::DataLossError("Failed to read buffer"));
      }
      if (!input.Seek(input.pos() - 2)) {
        return input.StatusOrAnnotate(
            absl::DataLossError("Failed to seek to offset"));
      }
      if (buffer == "<<") {  // Dictionary
        ABSL_RETURN_IF_ERROR(ReadDictionary(input, obj, depth + 1));
      } else {
        // Hexadecimal string
        ABSL_RETURN_IF_ERROR(ReadHexadecimalString(input, obj));
      }
      break;
    }
    case '/': {  // Name
      ABSL_RETURN_IF_ERROR(ReadName(input, obj));
      break;
    }
    case '[': {  // Array
      ABSL_RETURN_IF_ERROR(ReadArray(input, obj, depth + 1));
      break;
    }
    case 'n': {  // Null
      ABSL_RETURN_IF_ERROR(ReadNull(input, obj));
      break;
    }
    case 's': {  // Stream
      std::string buffer(6, '\0');
      if (!input.Read(6, buffer)) {
        return input.StatusOrAnnotate(
            absl::DataLossError("Failed to read buffer"));
      }
      if (!input.Seek(input.pos() - 6)) {
        return input.StatusOrAnnotate(
            absl::DataLossError("Failed to seek to offset"));
      }
      if (buffer == "stream") {
        return absl::InvalidArgumentError(
            "Stream must reside in an indirect object. Call "
            "ReadIndirectObject() instead.");
      } else {
        return absl::InvalidArgumentError(absl::StrCat(
            "Malformed keyword. Expected 'stream' but got '", buffer, "'"));
      }
      break;
    }
    default:
      return absl::InvalidArgumentError(
          absl::StrCat("Unsupported delimiter: 0x", absl::Hex(token),
                       " at offset ", input.pos()));
  }
  return absl::OkStatus();
}

absl::Status ReadIndirectObject(
    riegeli::Reader& input, int64_t obj_offset,
    absl::AnyInvocable<
        absl::StatusOr<IndirectObject>(const Object::IndirectReference&)>
        indirect_reference_resolver,
    IndirectObject& obj) {
  if (!input.Seek(obj_offset)) {
    return input.StatusOrAnnotate(
        absl::DataLossError("Failed to seek to offset"));
  }

  uint8_t token = 0x00;
  std::string buffer;

  // Read the object number.
  while (true) {
    if (buffer.size() >= kMaxNumberTokenLength) {
      return absl::InvalidArgumentError(
          absl::StrCat("Object number token exceeds maximum allowed length: ",
                       kMaxNumberTokenLength));
    }
    if (!input.ReadByte(token)) {
      return input.StatusOrAnnotate(
          absl::DataLossError("Failed to read beginning delimiter"));
    }
    if (IsPdfWhiteSpace(token)) {
      break;
    }
    absl::StrAppend(&buffer, std::string(1, token));
  }
  bool success = absl::SimpleAtoi(buffer, &obj.object_number);
  if (!success) {
    return absl::InvalidArgumentError(
        absl::StrCat("Failed to parse object number. Invalid value: ", buffer));
  }

  // Read the generation number.
  buffer.clear();
  while (true) {
    if (buffer.size() >= kMaxNumberTokenLength) {
      return absl::InvalidArgumentError(absl::StrCat(
          "Generation number token exceeds maximum allowed length: ",
          kMaxNumberTokenLength));
    }
    if (!input.ReadByte(token)) {
      return input.StatusOrAnnotate(
          absl::DataLossError("Failed to read beginning delimiter"));
    }
    if (IsPdfWhiteSpace(token)) {
      break;
    }
    absl::StrAppend(&buffer, std::string(1, token));
  }
  success = absl::SimpleAtoi(buffer, &obj.generation_number);
  if (!success) {
    return absl::InvalidArgumentError(absl::StrCat(
        "Failed to parse generation number. Invalid value: ", buffer));
  }

  // Read the enclosed object.
  ABSL_RETURN_IF_ERROR(SkipOverWhiteSpaces(input));
  if (!input.Read(3, buffer)) {
    return input.StatusOrAnnotate(absl::DataLossError("Failed to read buffer"));
  }
  if (buffer != "obj") {
    return absl::InvalidArgumentError(absl::StrCat(
        "Malformed keyword. Expected 'obj' but got '", buffer, "'"));
  }
  Object temp_obj;
  ABSL_RETURN_IF_ERROR(ReadObject(input, input.pos(), temp_obj));
  ABSL_RETURN_IF_ERROR(SkipOverWhiteSpaces(input));
  if (!input.Read(6, buffer)) {
    return input.StatusOrAnnotate(absl::DataLossError("Failed to read buffer"));
  }
  if (!input.Seek(input.pos() - 6)) {
    return input.StatusOrAnnotate(
        absl::DataLossError("Failed to seek to offset"));
  }
  if (buffer == "stream") {
    // Maker indicates that this is a stream object, hence the object preceding
    // it must be the stream dictionary.
    ABSL_ASSIGN_OR_RETURN(obj.stream_dictionary,
                          Object::As<Object::Dictionary>(temp_obj));

    ABSL_RETURN_IF_ERROR(SkipOverWhiteSpaces(input));
    // Determine the length of the stream.
    int64_t length = -1;
    if (const auto it = obj.stream_dictionary->entries.find("Length");
        it != obj.stream_dictionary->entries.end()) {
      if (std::holds_alternative<Object::IndirectReference>(it->second.value)) {
        ABSL_ASSIGN_OR_RETURN(
            auto indirect_ref,
            Object::As<Object::IndirectReference>(it->second));
        // Save the current input stream position, as the
        // `indirect_reference_resolver` might change it.
        auto pos = input.pos();
        ABSL_ASSIGN_OR_RETURN(auto indirect_length_obj,
                              indirect_reference_resolver(indirect_ref));

        ABSL_ASSIGN_OR_RETURN(auto length_obj, Object::As<Object::Integer>(
                                                   indirect_length_obj.object));
        length = length_obj.value;
        // Seek back to the saved position to continue reading the stream.
        if (!input.Seek(pos)) {
          return input.StatusOrAnnotate(
              absl::DataLossError("Failed to seek to offset"));
        }
      } else {
        ABSL_ASSIGN_OR_RETURN(auto length_obj,
                              Object::As<Object::Integer>(it->second));
        length = length_obj.value;
      }
    } else {
      return absl::DataLossError(
          "Stream dictionary does not contain a 'Length' entry.");
    }
    ABSL_RETURN_IF_ERROR(ReadStream(input, length, obj.object));
    // Skip over the end-of-object marker.
    ABSL_RETURN_IF_ERROR(SkipOverWhiteSpaces(input));
    if (!input.Read(6, buffer)) {
      return input.StatusOrAnnotate(
          absl::DataLossError("Failed to read buffer"));
    }
  } else {
    obj.object = std::move(temp_obj);
  }
  if (buffer != "endobj") {
    return absl::InvalidArgumentError(absl::StrCat(
        "Malformed keyword. Expected 'endobj' but got '", buffer, "'"));
  }
  return absl::OkStatus();
}

absl::Status SkipOverWhiteSpaces(riegeli::Reader& input) {
  uint8_t token = 0x00;
  while (true) {
    if (!input.ReadByte(token)) {
      return input.StatusOrAnnotate(
          absl::DataLossError("Failed to read beginning delimiter"));
    }
    if (token == '%') {
      // It's a comment, skip until EOL or EOF.
      while (true) {
        if (!input.ReadByte(token)) {
          return input.StatusOrAnnotate(
              absl::DataLossError("Failed to read beginning delimiter"));
        }
        if (token == 0x0a || token == 0x0d) {  // LF or CR
          break;
        }
      }
      continue;
    }
    if (!IsPdfWhiteSpace(token)) {
      // Seek back to the last non-whitespace character.
      if (!input.Seek(input.pos() - 1)) {
        return input.StatusOrAnnotate(
            absl::DataLossError("Failed to seek to offset"));
      }
      break;
    }
  }
  return absl::OkStatus();
}
}  // namespace credentio
