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