// Copyright 2017 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_attachment.h"
#include "public/fpdfview.h"
#include "testing/embedder_test.h"

class FPDFAttachmentEmbeddertest : public EmbedderTest {};

TEST_F(FPDFAttachmentEmbeddertest, ExtractAttachments) {
  // Open a file with two attachments.
  ASSERT_TRUE(OpenDocument("embedded_attachments.pdf"));
  EXPECT_EQ(2, FPDFDoc_GetAttachmentCount(document()));

  // Retrieve the first attachment.
  FPDF_ATTACHMENT attachment = FPDFDoc_GetAttachment(document(), 0);
  ASSERT_TRUE(attachment);

  // Check that the name of the first attachment is correct.
  unsigned long len = FPDFAttachment_GetName(attachment, nullptr, 0);
  std::vector<char> buf(len);
  EXPECT_EQ(12u, FPDFAttachment_GetName(attachment, buf.data(), len));
  EXPECT_STREQ(L"1.txt",
               GetPlatformWString(reinterpret_cast<unsigned short*>(buf.data()))
                   .c_str());

  // Check that the content of the first attachment is correct.
  len = FPDFAttachment_GetFile(attachment, nullptr, 0);
  buf.clear();
  buf.resize(len);
  ASSERT_EQ(4u, FPDFAttachment_GetFile(attachment, buf.data(), len));
  EXPECT_EQ(std::string("test"), std::string(buf.data(), 4));

  // Check that a non-existent key does not exist.
  EXPECT_FALSE(
      FPDFAttachment_HasKey(attachment, GetFPDFWideString(L"none").get()));

  // Check that the string value of a non-string dictionary entry is empty.
  std::unique_ptr<unsigned short, pdfium::FreeDeleter> size_key =
      GetFPDFWideString(L"Size");
  EXPECT_EQ(FPDF_OBJECT_NUMBER,
            FPDFAttachment_GetValueType(attachment, size_key.get()));
  EXPECT_EQ(2u, FPDFAttachment_GetStringValue(attachment, size_key.get(),
                                              nullptr, 0));

  // Check that the creation date of the first attachment is correct.
  std::unique_ptr<unsigned short, pdfium::FreeDeleter> date_key =
      GetFPDFWideString(L"CreationDate");
  len = FPDFAttachment_GetStringValue(attachment, date_key.get(), nullptr, 0);
  buf.clear();
  buf.resize(len);
  EXPECT_EQ(48u, FPDFAttachment_GetStringValue(attachment, date_key.get(),
                                               buf.data(), len));
  EXPECT_STREQ(L"D:20170712214438-07'00'",
               GetPlatformWString(reinterpret_cast<unsigned short*>(buf.data()))
                   .c_str());

  // Retrieve the second attachment.
  attachment = FPDFDoc_GetAttachment(document(), 1);
  ASSERT_TRUE(attachment);

  // Retrieve the second attachment file.
  len = FPDFAttachment_GetFile(attachment, nullptr, 0);
  buf.clear();
  buf.resize(len);
  EXPECT_EQ(5869u, FPDFAttachment_GetFile(attachment, buf.data(), len));

  // Check that the calculated checksum of the file data matches expectation.
  const char kCheckSum[] = "72afcddedf554dda63c0c88e06f1ce18";
  const wchar_t kCheckSumW[] = L"<72AFCDDEDF554DDA63C0C88E06F1CE18>";
  const std::string generated_checksum =
      GenerateMD5Base16(reinterpret_cast<uint8_t*>(buf.data()), len);
  EXPECT_EQ(kCheckSum, generated_checksum);

  // Check that the stored checksum matches expectation.
  std::unique_ptr<unsigned short, pdfium::FreeDeleter> checksum_key =
      GetFPDFWideString(L"CheckSum");
  len =
      FPDFAttachment_GetStringValue(attachment, checksum_key.get(), nullptr, 0);
  buf.clear();
  buf.resize(len);
  EXPECT_EQ(70u, FPDFAttachment_GetStringValue(attachment, checksum_key.get(),
                                               buf.data(), len));
  EXPECT_EQ(kCheckSumW,
            GetPlatformWString(reinterpret_cast<unsigned short*>(buf.data())));
}

TEST_F(FPDFAttachmentEmbeddertest, AddAttachments) {
  // Open a file with two attachments.
  ASSERT_TRUE(OpenDocument("embedded_attachments.pdf"));
  EXPECT_EQ(2, FPDFDoc_GetAttachmentCount(document()));

  // Check that adding an attachment with an empty name would fail.
  EXPECT_FALSE(FPDFDoc_AddAttachment(document(), nullptr));

  // Add an attachment to the beginning of the embedded file list.
  std::unique_ptr<unsigned short, pdfium::FreeDeleter> file_name =
      GetFPDFWideString(L"0.txt");
  FPDF_ATTACHMENT attachment =
      FPDFDoc_AddAttachment(document(), file_name.get());

  // Check that writing to a file with nullptr but non-zero bytes would fail.
  EXPECT_FALSE(FPDFAttachment_SetFile(attachment, document(), nullptr, 10));

  // Set the new attachment's file.
  constexpr char kContents1[] = "Hello!";
  EXPECT_TRUE(FPDFAttachment_SetFile(attachment, document(), kContents1,
                                     strlen(kContents1)));

  // Verify the name of the new attachment (i.e. the first attachment).
  attachment = FPDFDoc_GetAttachment(document(), 0);
  ASSERT_TRUE(attachment);
  unsigned long len = FPDFAttachment_GetName(attachment, nullptr, 0);
  std::vector<char> buf(len);
  EXPECT_EQ(12u, FPDFAttachment_GetName(attachment, buf.data(), len));
  EXPECT_STREQ(L"0.txt",
               GetPlatformWString(reinterpret_cast<unsigned short*>(buf.data()))
                   .c_str());

  // Verify the content of the new attachment (i.e. the first attachment).
  len = FPDFAttachment_GetFile(attachment, nullptr, 0);
  buf.clear();
  buf.resize(len);
  ASSERT_EQ(6u, FPDFAttachment_GetFile(attachment, buf.data(), len));
  EXPECT_EQ(std::string(kContents1), std::string(buf.data(), 6));

  // Add an attachment to the end of the embedded file list and set its file.
  file_name = GetFPDFWideString(L"z.txt");
  attachment = FPDFDoc_AddAttachment(document(), file_name.get());
  constexpr char kContents2[] = "World!";
  EXPECT_TRUE(FPDFAttachment_SetFile(attachment, document(), kContents2,
                                     strlen(kContents2)));
  EXPECT_EQ(4, FPDFDoc_GetAttachmentCount(document()));

  // Verify the name of the new attachment (i.e. the fourth attachment).
  attachment = FPDFDoc_GetAttachment(document(), 3);
  ASSERT_TRUE(attachment);
  len = FPDFAttachment_GetName(attachment, nullptr, 0);
  buf.clear();
  buf.resize(len);
  EXPECT_EQ(12u, FPDFAttachment_GetName(attachment, buf.data(), len));
  EXPECT_STREQ(L"z.txt",
               GetPlatformWString(reinterpret_cast<unsigned short*>(buf.data()))
                   .c_str());

  // Verify the content of the new attachment (i.e. the fourth attachment).
  len = FPDFAttachment_GetFile(attachment, nullptr, 0);
  buf.clear();
  buf.resize(len);
  ASSERT_EQ(6u, FPDFAttachment_GetFile(attachment, buf.data(), len));
  EXPECT_EQ(std::string(kContents2), std::string(buf.data(), 6));
}

TEST_F(FPDFAttachmentEmbeddertest, AddAttachmentsWithParams) {
  // Open a file with two attachments.
  ASSERT_TRUE(OpenDocument("embedded_attachments.pdf"));
  EXPECT_EQ(2, FPDFDoc_GetAttachmentCount(document()));

  // Add an attachment to the embedded file list.
  std::unique_ptr<unsigned short, pdfium::FreeDeleter> file_name =
      GetFPDFWideString(L"5.txt");
  FPDF_ATTACHMENT attachment =
      FPDFDoc_AddAttachment(document(), file_name.get());
  constexpr char kContents[] = "Hello World!";
  EXPECT_TRUE(FPDFAttachment_SetFile(attachment, document(), kContents,
                                     strlen(kContents)));

  // Set the date to be an arbitrary value.
  std::unique_ptr<unsigned short, pdfium::FreeDeleter> date_key =
      GetFPDFWideString(L"CreationDate");
  constexpr wchar_t kDateW[] = L"D:20170720161527-04'00'";
  std::unique_ptr<unsigned short, pdfium::FreeDeleter> ws_date =
      GetFPDFWideString(kDateW);
  EXPECT_TRUE(
      FPDFAttachment_SetStringValue(attachment, date_key.get(), ws_date.get()));

  // Set the checksum to be an arbitrary value.
  std::unique_ptr<unsigned short, pdfium::FreeDeleter> checksum_key =
      GetFPDFWideString(L"CheckSum");
  constexpr wchar_t kCheckSumW[] = L"<ABCDEF01234567899876543210FEDCBA>";
  std::unique_ptr<unsigned short, pdfium::FreeDeleter> ws_checksum =
      GetFPDFWideString(kCheckSumW);
  EXPECT_TRUE(FPDFAttachment_SetStringValue(attachment, checksum_key.get(),
                                            ws_checksum.get()));

  // Verify the name of the new attachment (i.e. the second attachment).
  attachment = FPDFDoc_GetAttachment(document(), 1);
  ASSERT_TRUE(attachment);
  unsigned long len = FPDFAttachment_GetName(attachment, nullptr, 0);
  std::vector<char> buf(len);
  EXPECT_EQ(12u, FPDFAttachment_GetName(attachment, buf.data(), len));
  EXPECT_STREQ(L"5.txt",
               GetPlatformWString(reinterpret_cast<unsigned short*>(buf.data()))
                   .c_str());

  // Verify the content of the new attachment.
  len = FPDFAttachment_GetFile(attachment, nullptr, 0);
  buf.clear();
  buf.resize(len);
  ASSERT_EQ(12u, FPDFAttachment_GetFile(attachment, buf.data(), len));
  EXPECT_EQ(std::string(kContents), std::string(buf.data(), 12));

  // Verify the creation date of the new attachment.
  len = FPDFAttachment_GetStringValue(attachment, date_key.get(), nullptr, 0);
  buf.clear();
  buf.resize(len);
  EXPECT_EQ(48u, FPDFAttachment_GetStringValue(attachment, date_key.get(),
                                               buf.data(), len));
  EXPECT_STREQ(kDateW,
               GetPlatformWString(reinterpret_cast<unsigned short*>(buf.data()))
                   .c_str());

  // Verify the checksum of the new attachment.
  len =
      FPDFAttachment_GetStringValue(attachment, checksum_key.get(), nullptr, 0);
  buf.clear();
  buf.resize(len);
  EXPECT_EQ(70u, FPDFAttachment_GetStringValue(attachment, checksum_key.get(),
                                               buf.data(), len));
  EXPECT_STREQ(kCheckSumW,
               GetPlatformWString(reinterpret_cast<unsigned short*>(buf.data()))
                   .c_str());

  // Overwrite the existing file with empty content, and check that the checksum
  // gets updated to the correct value.
  EXPECT_TRUE(FPDFAttachment_SetFile(attachment, document(), nullptr, 0));
  EXPECT_EQ(0u, FPDFAttachment_GetFile(attachment, nullptr, 0));
  len =
      FPDFAttachment_GetStringValue(attachment, checksum_key.get(), nullptr, 0);
  buf.clear();
  buf.resize(len);
  EXPECT_EQ(70u, FPDFAttachment_GetStringValue(attachment, checksum_key.get(),
                                               buf.data(), len));
  EXPECT_EQ(L"<D41D8CD98F00B204E9800998ECF8427E>",
            GetPlatformWString(reinterpret_cast<unsigned short*>(buf.data())));
}