// 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 "testing/xfa_js_embedder_test.h"

#include <string>

#include "fpdfsdk/cpdfsdk_helpers.h"
#include "fpdfsdk/fpdfxfa/cpdfxfa_context.h"
#include "fxjs/fxv8.h"
#include "fxjs/xfa/cfxjse_engine.h"
#include "fxjs/xfa/cfxjse_isolatetracker.h"
#include "fxjs/xfa/cfxjse_value.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/base/check_op.h"

XFAJSEmbedderTest::XFAJSEmbedderTest() = default;

XFAJSEmbedderTest::~XFAJSEmbedderTest() = default;

void XFAJSEmbedderTest::SetUp() {
  JSEmbedderTest::SetUp();
}

void XFAJSEmbedderTest::TearDown() {
  value_.Reset();
  script_context_ = nullptr;

  JSEmbedderTest::TearDown();
}

CXFA_Document* XFAJSEmbedderTest::GetXFADocument() const {
  auto* pDoc = CPDFDocumentFromFPDFDocument(document());
  if (!pDoc)
    return nullptr;

  auto* pContext = static_cast<CPDFXFA_Context*>(pDoc->GetExtension());
  if (!pContext)
    return nullptr;

  return pContext->GetXFADoc()->GetXFADoc();
}

v8::Local<v8::Value> XFAJSEmbedderTest::GetValue() const {
  return v8::Local<v8::Value>::New(isolate(), value_);
}

bool XFAJSEmbedderTest::OpenDocumentWithOptions(
    const std::string& filename,
    const char* password,
    LinearizeOption linearize_option,
    JavaScriptOption javascript_option) {
  // JS required for XFA.
  DCHECK_EQ(javascript_option, JavaScriptOption::kEnableJavaScript);
  if (!EmbedderTest::OpenDocumentWithOptions(
          filename, password, linearize_option, javascript_option)) {
    return false;
  }
  script_context_ = GetXFADocument()->GetScriptContext();
  return true;
}

bool XFAJSEmbedderTest::Execute(ByteStringView input) {
  CFXJSE_ScopeUtil_IsolateHandleContext scope(script_context_->GetJseContext());
  if (ExecuteHelper(input))
    return true;

  fprintf(stderr, "FormCalc: %.*s\n", static_cast<int>(input.GetLength()),
          input.unterminated_c_str());

  v8::Local<v8::Value> result = GetValue();
  if (!fxv8::IsArray(result))
    return false;

  v8::Local<v8::Value> msg = fxv8::ReentrantGetArrayElementHelper(
      isolate(), result.As<v8::Array>(), 1);
  if (!fxv8::IsString(msg))
    return false;

  WideString str = fxv8::ReentrantToWideStringHelper(isolate(), msg);
  if (!str.IsEmpty())
    fprintf(stderr, "JS ERROR: %ls\n", str.c_str());
  return false;
}

bool XFAJSEmbedderTest::ExecuteSilenceFailure(ByteStringView input) {
  CFXJSE_ScopeUtil_IsolateHandleContext scope(script_context_->GetJseContext());
  return ExecuteHelper(input);
}

bool XFAJSEmbedderTest::ExecuteHelper(ByteStringView input) {
  auto value = std::make_unique<CFXJSE_Value>();
  bool ret = script_context_->RunScript(
      CXFA_Script::Type::Formcalc, WideString::FromUTF8(input).AsStringView(),
      value.get(), GetXFADocument()->GetRoot());
  value_.Reset(isolate(), value->GetValue(isolate()));
  return ret;
}
