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

#include <vector>

#include "core/fxcrt/compiler_specific.h"
#include "core/fxcrt/fx_memcpy_wrappers.h"
#include "core/fxcrt/fx_memory.h"
#include "public/fpdf_javascript.h"
#include "public/fpdfview.h"
#include "testing/embedder_test.h"
#include "testing/fx_string_testhelpers.h"
#include "testing/utils/hash.h"

class FPDFJavaScriptEmbedderTest : public EmbedderTest {};

TEST_F(FPDFJavaScriptEmbedderTest, CountJS) {
  // Open a file with JS.
  ASSERT_TRUE(OpenDocument("bug_679649.pdf"));
  EXPECT_EQ(1, FPDFDoc_GetJavaScriptActionCount(document()));
}

TEST_F(FPDFJavaScriptEmbedderTest, CountNoJS) {
  // Open a file without JS.
  ASSERT_TRUE(OpenDocument("hello_world.pdf"));
  EXPECT_EQ(0, FPDFDoc_GetJavaScriptActionCount(document()));

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

TEST_F(FPDFJavaScriptEmbedderTest, GetJS) {
  ASSERT_TRUE(OpenDocument("js.pdf"));
  EXPECT_EQ(5, FPDFDoc_GetJavaScriptActionCount(document()));

  ScopedFPDFJavaScriptAction js;
  js.reset(FPDFDoc_GetJavaScriptAction(document(), -1));
  EXPECT_FALSE(js);
  js.reset(FPDFDoc_GetJavaScriptAction(document(), 5));
  EXPECT_FALSE(js);
  js.reset(FPDFDoc_GetJavaScriptAction(nullptr, -1));
  EXPECT_FALSE(js);
  js.reset(FPDFDoc_GetJavaScriptAction(nullptr, 0));
  EXPECT_FALSE(js);
  js.reset(FPDFDoc_GetJavaScriptAction(nullptr, 1));
  EXPECT_FALSE(js);
  js.reset(FPDFDoc_GetJavaScriptAction(nullptr, 2));
  EXPECT_FALSE(js);
  js.reset(FPDFDoc_GetJavaScriptAction(nullptr, 5));
  EXPECT_FALSE(js);

  js.reset(FPDFDoc_GetJavaScriptAction(document(), 0));
  EXPECT_TRUE(js);
  js.reset(FPDFDoc_GetJavaScriptAction(document(), 1));
  EXPECT_TRUE(js);
  js.reset(FPDFDoc_GetJavaScriptAction(document(), 2));
  EXPECT_FALSE(js);
  js.reset(FPDFDoc_GetJavaScriptAction(document(), 3));
  EXPECT_FALSE(js);
  js.reset(FPDFDoc_GetJavaScriptAction(document(), 4));
  EXPECT_FALSE(js);
}

TEST_F(FPDFJavaScriptEmbedderTest, GetJSName) {
  ASSERT_TRUE(OpenDocument("bug_679649.pdf"));
  ScopedFPDFJavaScriptAction js(FPDFDoc_GetJavaScriptAction(document(), 0));
  ASSERT_TRUE(js);

  {
    FPDF_WCHAR buf[10];
    EXPECT_EQ(0u, FPDFJavaScriptAction_GetName(nullptr, nullptr, 0));
    EXPECT_EQ(0u, FPDFJavaScriptAction_GetName(nullptr, buf, 0));
    EXPECT_EQ(0u, FPDFJavaScriptAction_GetName(nullptr, buf, sizeof(buf)));
  }

  static constexpr size_t kExpectedLength = 22;
  ASSERT_EQ(kExpectedLength,
            FPDFJavaScriptAction_GetName(js.get(), nullptr, 0));

  // Check that the name not returned if the buffer is too small.
  // The result buffer should be overwritten with an empty string.
  std::vector<FPDF_WCHAR> buf = GetFPDFWideStringBuffer(kExpectedLength);
  // Write in the buffer to verify it's not overwritten.
  UNSAFE_TODO(FXSYS_memcpy(buf.data(), "abcdefgh", 8));
  EXPECT_EQ(kExpectedLength, FPDFJavaScriptAction_GetName(js.get(), buf.data(),
                                                          kExpectedLength - 1));
  EXPECT_EQ(0, memcmp(buf.data(), "abcdefgh", 8));

  EXPECT_EQ(kExpectedLength, FPDFJavaScriptAction_GetName(js.get(), buf.data(),
                                                          kExpectedLength));
  EXPECT_EQ(L"startDelay", GetPlatformWString(buf.data()));
}

TEST_F(FPDFJavaScriptEmbedderTest, GetJSScript) {
  ASSERT_TRUE(OpenDocument("bug_679649.pdf"));
  ScopedFPDFJavaScriptAction js(FPDFDoc_GetJavaScriptAction(document(), 0));
  ASSERT_TRUE(js);

  {
    FPDF_WCHAR buf[10];
    EXPECT_EQ(0u, FPDFJavaScriptAction_GetScript(nullptr, nullptr, 0));
    EXPECT_EQ(0u, FPDFJavaScriptAction_GetScript(nullptr, buf, 0));
    EXPECT_EQ(0u, FPDFJavaScriptAction_GetScript(nullptr, buf, sizeof(buf)));
  }

  static constexpr size_t kExpectedLength = 218;
  ASSERT_EQ(kExpectedLength,
            FPDFJavaScriptAction_GetScript(js.get(), nullptr, 0));

  // Check that the string value of an AP is not returned if the buffer is too
  // small. The result buffer should be overwritten with an empty string.
  std::vector<FPDF_WCHAR> buf = GetFPDFWideStringBuffer(kExpectedLength);
  // Write in the buffer to verify it's not overwritten.
  UNSAFE_TODO(FXSYS_memcpy(buf.data(), "abcdefgh", 8));
  EXPECT_EQ(kExpectedLength, FPDFJavaScriptAction_GetScript(
                                 js.get(), buf.data(), kExpectedLength - 1));
  EXPECT_EQ(0, memcmp(buf.data(), "abcdefgh", 8));

  static const wchar_t kExpectedScript[] =
      L"function ping() {\n  app.alert(\"ping\");\n}\n"
      L"var timer = app.setTimeOut(\"ping()\", 100);\napp.clearTimeOut(timer);";
  EXPECT_EQ(kExpectedLength, FPDFJavaScriptAction_GetScript(
                                 js.get(), buf.data(), kExpectedLength));
  EXPECT_EQ(kExpectedScript, GetPlatformWString(buf.data()));
}
