// 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 <vector>

#include "public/fpdf_signature.h"
#include "testing/embedder_test.h"
#include "testing/fx_string_testhelpers.h"
#include "third_party/base/cxx17_backports.h"

class FPDFSignatureEmbedderTest : public EmbedderTest {};

TEST_F(FPDFSignatureEmbedderTest, GetSignatureCount) {
  ASSERT_TRUE(OpenDocument("two_signatures.pdf"));
  EXPECT_EQ(2, FPDF_GetSignatureCount(document()));
}

TEST_F(FPDFSignatureEmbedderTest, GetSignatureCountZero) {
  ASSERT_TRUE(OpenDocument("hello_world.pdf"));
  EXPECT_EQ(0, FPDF_GetSignatureCount(document()));

  // Provide no document.
  EXPECT_EQ(-1, FPDF_GetSignatureCount(nullptr));
}

TEST_F(FPDFSignatureEmbedderTest, GetSignatureObject) {
  ASSERT_TRUE(OpenDocument("two_signatures.pdf"));
  // Different, non-null signature objects are returned.
  FPDF_SIGNATURE signature1 = FPDF_GetSignatureObject(document(), 0);
  EXPECT_NE(nullptr, signature1);
  FPDF_SIGNATURE signature2 = FPDF_GetSignatureObject(document(), 1);
  EXPECT_NE(nullptr, signature2);
  EXPECT_NE(signature1, signature2);

  // Out of bounds.
  EXPECT_EQ(nullptr, FPDF_GetSignatureObject(document(), -1));
  EXPECT_EQ(nullptr, FPDF_GetSignatureObject(document(), 2));

  // Provide no document.
  EXPECT_EQ(nullptr, FPDF_GetSignatureObject(nullptr, 0));
}

TEST_F(FPDFSignatureEmbedderTest, GetContents) {
  ASSERT_TRUE(OpenDocument("two_signatures.pdf"));
  FPDF_SIGNATURE signature = FPDF_GetSignatureObject(document(), 0);
  EXPECT_NE(nullptr, signature);

  // FPDFSignatureObj_GetContents() positive testing.
  unsigned long size = FPDFSignatureObj_GetContents(signature, nullptr, 0);
  const uint8_t kExpectedContents[] = {0x30, 0x80, 0x06, 0x09, 0x2A, 0x86, 0x48,
                                       0x86, 0xF7, 0x0D, 0x01, 0x07, 0x02, 0xA0,
                                       0x80, 0x30, 0x80, 0x02, 0x01, 0x01};
  ASSERT_EQ(sizeof(kExpectedContents), size);
  std::vector<char> contents(size);
  ASSERT_EQ(size,
            FPDFSignatureObj_GetContents(signature, contents.data(), size));
  ASSERT_EQ(0, memcmp(kExpectedContents, contents.data(), size));

  // FPDFSignatureObj_GetContents() negative testing.
  ASSERT_EQ(0U, FPDFSignatureObj_GetContents(nullptr, nullptr, 0));

  contents.resize(2);
  contents[0] = 'x';
  contents[1] = '\0';
  size =
      FPDFSignatureObj_GetContents(signature, contents.data(), contents.size());
  ASSERT_EQ(sizeof(kExpectedContents), size);
  EXPECT_EQ('x', contents[0]);
  EXPECT_EQ('\0', contents[1]);
}

TEST_F(FPDFSignatureEmbedderTest, GetByteRange) {
  ASSERT_TRUE(OpenDocument("two_signatures.pdf"));
  FPDF_SIGNATURE signature = FPDF_GetSignatureObject(document(), 0);
  EXPECT_NE(nullptr, signature);

  // FPDFSignatureObj_GetByteRange() positive testing.
  unsigned long size = FPDFSignatureObj_GetByteRange(signature, nullptr, 0);
  const std::vector<int> kExpectedByteRange{0, 10, 30, 10};
  ASSERT_EQ(kExpectedByteRange.size(), size);
  std::vector<int> byte_range(size);
  ASSERT_EQ(size,
            FPDFSignatureObj_GetByteRange(signature, byte_range.data(), size));
  ASSERT_EQ(kExpectedByteRange, byte_range);

  // FPDFSignatureObj_GetByteRange() negative testing.
  ASSERT_EQ(0U, FPDFSignatureObj_GetByteRange(nullptr, nullptr, 0));

  byte_range.resize(2);
  byte_range[0] = 0;
  byte_range[1] = 1;
  size = FPDFSignatureObj_GetByteRange(signature, byte_range.data(),
                                       byte_range.size());
  ASSERT_EQ(kExpectedByteRange.size(), size);
  EXPECT_EQ(0, byte_range[0]);
  EXPECT_EQ(1, byte_range[1]);
}

TEST_F(FPDFSignatureEmbedderTest, GetSubFilter) {
  ASSERT_TRUE(OpenDocument("two_signatures.pdf"));
  FPDF_SIGNATURE signature = FPDF_GetSignatureObject(document(), 0);
  EXPECT_NE(nullptr, signature);

  // FPDFSignatureObj_GetSubFilter() positive testing.
  unsigned long size = FPDFSignatureObj_GetSubFilter(signature, nullptr, 0);
  const char kExpectedSubFilter[] = "ETSI.CAdES.detached";
  ASSERT_EQ(sizeof(kExpectedSubFilter), size);
  std::vector<char> sub_filter(size);
  ASSERT_EQ(size,
            FPDFSignatureObj_GetSubFilter(signature, sub_filter.data(), size));
  ASSERT_EQ(0, memcmp(kExpectedSubFilter, sub_filter.data(), size));

  // FPDFSignatureObj_GetSubFilter() negative testing.
  ASSERT_EQ(0U, FPDFSignatureObj_GetSubFilter(nullptr, nullptr, 0));

  sub_filter.resize(2);
  sub_filter[0] = 'x';
  sub_filter[1] = '\0';
  size = FPDFSignatureObj_GetSubFilter(signature, sub_filter.data(),
                                       sub_filter.size());
  ASSERT_EQ(sizeof(kExpectedSubFilter), size);
  EXPECT_EQ('x', sub_filter[0]);
  EXPECT_EQ('\0', sub_filter[1]);
}

TEST_F(FPDFSignatureEmbedderTest, GetSubFilterNoKeyExists) {
  ASSERT_TRUE(OpenDocument("signature_no_sub_filter.pdf"));
  FPDF_SIGNATURE signature = FPDF_GetSignatureObject(document(), 0);
  EXPECT_NE(nullptr, signature);

  // FPDFSignatureObj_GetSubFilter() negative testing: no SubFilter
  ASSERT_EQ(0U, FPDFSignatureObj_GetSubFilter(signature, nullptr, 0));
}

TEST_F(FPDFSignatureEmbedderTest, GetReason) {
  ASSERT_TRUE(OpenDocument("signature_reason.pdf"));
  FPDF_SIGNATURE signature = FPDF_GetSignatureObject(document(), 0);
  EXPECT_NE(nullptr, signature);

  // FPDFSignatureObj_GetReason() positive testing.
  constexpr char kReason[] = "test reason";
  // Return value includes the terminating NUL that is provided.
  constexpr unsigned long kReasonUTF16Size = pdfium::size(kReason) * 2;
  constexpr wchar_t kReasonWide[] = L"test reason";
  unsigned long size = FPDFSignatureObj_GetReason(signature, nullptr, 0);
  ASSERT_EQ(kReasonUTF16Size, size);

  std::vector<unsigned short> buffer(size);
  ASSERT_EQ(size, FPDFSignatureObj_GetReason(signature, buffer.data(), size));
  ASSERT_EQ(kReasonWide, GetPlatformWString(buffer.data()));

  // FPDFSignatureObj_GetReason() negative testing.
  ASSERT_EQ(0U, FPDFSignatureObj_GetReason(nullptr, nullptr, 0));

  // Buffer is too small, ensure it's not modified.
  buffer.resize(2);
  buffer[0] = 'x';
  buffer[1] = '\0';
  size = FPDFSignatureObj_GetReason(signature, buffer.data(), buffer.size());
  ASSERT_EQ(kReasonUTF16Size, size);
  EXPECT_EQ('x', buffer[0]);
  EXPECT_EQ('\0', buffer[1]);
}

TEST_F(FPDFSignatureEmbedderTest, GetTime) {
  ASSERT_TRUE(OpenDocument("two_signatures.pdf"));
  FPDF_SIGNATURE signature = FPDF_GetSignatureObject(document(), 0);
  EXPECT_NE(nullptr, signature);

  // FPDFSignatureObj_GetTime() positive testing.
  unsigned long size = FPDFSignatureObj_GetTime(signature, nullptr, 0);
  const char kExpectedTime[] = "D:20200624093114+02'00'";
  ASSERT_EQ(sizeof(kExpectedTime), size);
  std::vector<char> time_buffer(size);
  ASSERT_EQ(size,
            FPDFSignatureObj_GetTime(signature, time_buffer.data(), size));
  ASSERT_EQ(0, memcmp(kExpectedTime, time_buffer.data(), size));

  // FPDFSignatureObj_GetTime() negative testing.
  ASSERT_EQ(0U, FPDFSignatureObj_GetTime(nullptr, nullptr, 0));

  time_buffer.resize(2);
  time_buffer[0] = 'x';
  time_buffer[1] = '\0';
  size = FPDFSignatureObj_GetTime(signature, time_buffer.data(),
                                  time_buffer.size());
  ASSERT_EQ(sizeof(kExpectedTime), size);
  EXPECT_EQ('x', time_buffer[0]);
  EXPECT_EQ('\0', time_buffer[1]);
}

TEST_F(FPDFSignatureEmbedderTest, GetDocMDPPermission) {
  ASSERT_TRUE(OpenDocument("docmdp.pdf"));
  FPDF_SIGNATURE signature = FPDF_GetSignatureObject(document(), 0);
  ASSERT_NE(nullptr, signature);

  // FPDFSignatureObj_GetDocMDPPermission() positive testing.
  unsigned int permission = FPDFSignatureObj_GetDocMDPPermission(signature);
  EXPECT_EQ(1U, permission);

  // FPDFSignatureObj_GetDocMDPPermission() negative testing.
  EXPECT_EQ(0U, FPDFSignatureObj_GetDocMDPPermission(nullptr));
}
