// 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)));
  }

  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)));
  }

  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()));
}
