// Copyright 2020 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "public/fpdf_signature.h"

#include "core/fpdfapi/parser/cpdf_array.h"
#include "core/fpdfapi/parser/cpdf_dictionary.h"
#include "core/fpdfapi/parser/cpdf_document.h"
#include "fpdfsdk/cpdfsdk_helpers.h"
#include "third_party/base/stl_util.h"

namespace {

std::vector<CPDF_Dictionary*> CollectSignatures(CPDF_Document* doc) {
  std::vector<CPDF_Dictionary*> signatures;
  CPDF_Dictionary* root = doc->GetRoot();
  if (!root)
    return signatures;

  const CPDF_Dictionary* acro_form = root->GetDictFor("AcroForm");
  if (!acro_form)
    return signatures;

  const CPDF_Array* fields = acro_form->GetArrayFor("Fields");
  if (!fields)
    return signatures;

  CPDF_ArrayLocker locker(fields);
  for (auto& field : locker) {
    CPDF_Dictionary* field_dict = field->GetDict();
    if (field_dict && field_dict->GetNameFor("FT") == "Sig")
      signatures.push_back(field_dict);
  }
  return signatures;
}

}  // namespace

FPDF_EXPORT int FPDF_CALLCONV FPDF_GetSignatureCount(FPDF_DOCUMENT document) {
  auto* doc = CPDFDocumentFromFPDFDocument(document);
  if (!doc)
    return -1;

  return pdfium::CollectionSize<int>(CollectSignatures(doc));
}

FPDF_EXPORT FPDF_SIGNATURE FPDF_CALLCONV
FPDF_GetSignatureObject(FPDF_DOCUMENT document, int index) {
  auto* doc = CPDFDocumentFromFPDFDocument(document);
  if (!doc)
    return nullptr;

  std::vector<CPDF_Dictionary*> signatures = CollectSignatures(doc);
  if (!pdfium::IndexInBounds(signatures, index))
    return nullptr;

  return FPDFSignatureFromCPDFDictionary(signatures[index]);
}

FPDF_EXPORT unsigned long FPDF_CALLCONV
FPDFSignatureObj_GetContents(FPDF_SIGNATURE signature,
                             void* buffer,
                             unsigned long length) {
  CPDF_Dictionary* signature_dict = CPDFDictionaryFromFPDFSignature(signature);
  if (!signature_dict)
    return 0;

  CPDF_Dictionary* value_dict = signature_dict->GetDictFor("V");
  if (!value_dict)
    return 0;

  ByteString contents = value_dict->GetStringFor("Contents");
  unsigned long contents_len = contents.GetLength();
  if (buffer && length >= contents_len)
    memcpy(buffer, contents.c_str(), contents_len);

  return contents_len;
}

FPDF_EXPORT unsigned long FPDF_CALLCONV
FPDFSignatureObj_GetByteRange(FPDF_SIGNATURE signature,
                              int* buffer,
                              unsigned long length) {
  CPDF_Dictionary* signature_dict = CPDFDictionaryFromFPDFSignature(signature);
  if (!signature_dict)
    return 0;

  CPDF_Dictionary* value_dict = signature_dict->GetDictFor("V");
  if (!value_dict)
    return 0;

  const CPDF_Array* byte_range = value_dict->GetArrayFor("ByteRange");
  if (!byte_range)
    return 0;

  unsigned long byte_range_len = byte_range->size();
  if (buffer && length >= byte_range_len) {
    for (size_t i = 0; i < byte_range_len; ++i)
      buffer[i] = byte_range->GetIntegerAt(i);
  }

  return byte_range_len;
}

FPDF_EXPORT unsigned long FPDF_CALLCONV
FPDFSignatureObj_GetSubFilter(FPDF_SIGNATURE signature,
                              char* buffer,
                              unsigned long length) {
  CPDF_Dictionary* signature_dict = CPDFDictionaryFromFPDFSignature(signature);
  if (!signature_dict)
    return 0;

  CPDF_Dictionary* value_dict = signature_dict->GetDictFor("V");
  if (!value_dict || !value_dict->KeyExist("SubFilter"))
    return 0;

  ByteString sub_filter = value_dict->GetNameFor("SubFilter");
  return NulTerminateMaybeCopyAndReturnLength(sub_filter, buffer, length);
}

FPDF_EXPORT unsigned long FPDF_CALLCONV
FPDFSignatureObj_GetReason(FPDF_SIGNATURE signature,
                           void* buffer,
                           unsigned long length) {
  CPDF_Dictionary* signature_dict = CPDFDictionaryFromFPDFSignature(signature);
  if (!signature_dict)
    return 0;

  CPDF_Dictionary* value_dict = signature_dict->GetDictFor("V");
  if (!value_dict)
    return 0;

  const CPDF_Object* obj = value_dict->GetObjectFor("Reason");
  if (!obj || !obj->IsString())
    return 0;

  return Utf16EncodeMaybeCopyAndReturnLength(obj->GetUnicodeText(), buffer,
                                             length);
}

FPDF_EXPORT unsigned long FPDF_CALLCONV
FPDFSignatureObj_GetTime(FPDF_SIGNATURE signature,
                         char* buffer,
                         unsigned long length) {
  CPDF_Dictionary* signature_dict = CPDFDictionaryFromFPDFSignature(signature);
  if (!signature_dict)
    return 0;

  CPDF_Dictionary* value_dict = signature_dict->GetDictFor("V");
  if (!value_dict)
    return 0;

  const CPDF_Object* obj = value_dict->GetObjectFor("M");
  if (!obj || !obj->IsString())
    return 0;

  return NulTerminateMaybeCopyAndReturnLength(obj->GetString(), buffer, length);
}

FPDF_EXPORT unsigned int FPDF_CALLCONV
FPDFSignatureObj_GetDocMDPPermission(FPDF_SIGNATURE signature) {
  int permission = 0;
  CPDF_Dictionary* signature_dict = CPDFDictionaryFromFPDFSignature(signature);
  if (!signature_dict)
    return permission;

  CPDF_Dictionary* value_dict = signature_dict->GetDictFor("V");
  if (!value_dict)
    return permission;

  CPDF_Array* references = value_dict->GetArrayFor("Reference");
  if (!references)
    return permission;

  CPDF_ArrayLocker locker(references);
  for (auto& reference : locker) {
    CPDF_Dictionary* reference_dict = reference->GetDict();
    if (!reference_dict)
      continue;

    ByteString transform_method = reference_dict->GetNameFor("TransformMethod");
    if (transform_method != "DocMDP")
      continue;

    CPDF_Dictionary* transform_params =
        reference_dict->GetDictFor("TransformParams");
    if (!transform_params)
      continue;

    // Valid values are 1, 2 and 3; 2 is the default.
    permission = transform_params->GetIntegerFor("P", 2);
    if (permission < 1 || permission > 3)
      permission = 0;

    return permission;
  }

  return permission;
}
