// Copyright 2016 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.

// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

#include "fxjs/xfa/cfxjse_context.h"

#include <utility>

#include "fxjs/cfxjs_engine.h"
#include "fxjs/fxv8.h"
#include "fxjs/xfa/cfxjse_class.h"
#include "fxjs/xfa/cfxjse_isolatetracker.h"
#include "fxjs/xfa/cfxjse_runtimedata.h"
#include "fxjs/xfa/cfxjse_value.h"
#include "fxjs/xfa/cjx_object.h"
#include "third_party/base/check.h"
#include "third_party/base/check_op.h"
#include "third_party/base/ptr_util.h"
#include "v8/include/v8-exception.h"
#include "v8/include/v8-function.h"
#include "v8/include/v8-message.h"
#include "v8/include/v8-script.h"
#include "xfa/fxfa/parser/cxfa_thisproxy.h"

namespace {

const char szCompatibleModeScript[] =
    "(function(global, list) {\n"
    "  'use strict';\n"
    "  var objname;\n"
    "  for (objname in list) {\n"
    "    var globalobj = global[objname];\n"
    "    if (globalobj) {\n"
    "      list[objname].forEach(function(name) {\n"
    "        if (!globalobj[name]) {\n"
    "          Object.defineProperty(globalobj, name, {\n"
    "            writable: true,\n"
    "            enumerable: false,\n"
    "            value: (function(obj) {\n"
    "              if (arguments.length === 0) {\n"
    "                throw new TypeError('missing argument 0 when calling "
    "                    function ' + objname + '.' + name);\n"
    "              }\n"
    "              return globalobj.prototype[name].apply(obj, "
    "                  Array.prototype.slice.call(arguments, 1));\n"
    "            })\n"
    "          });\n"
    "        }\n"
    "      });\n"
    "    }\n"
    "  }\n"
    "}(this, {String: ['substr', 'toUpperCase']}));";

const char szConsoleScript[] =
    "console.show = function() {};\n"
    "\n"
    "console.println = function(...args) {\n"
    "  this.log(...args);\n"
    "};";

// Only address matters, values are for humans debuging here.  Keep these
// wchar_t to prevent the compiler from doing something clever, like
// aligning them on a byte boundary to save space, which would make them
// incompatible for use as V8 aligned pointers.
const wchar_t kFXJSEHostObjectTag[] = L"FXJSE Host Object";
const wchar_t kFXJSEProxyObjectTag[] = L"FXJSE Proxy Object";

v8::Local<v8::Object> CreateReturnValue(v8::Isolate* pIsolate,
                                        v8::TryCatch* trycatch) {
  v8::Local<v8::Object> hReturnValue = v8::Object::New(pIsolate);
  if (!trycatch->HasCaught())
    return hReturnValue;

  v8::Local<v8::Message> hMessage = trycatch->Message();
  if (hMessage.IsEmpty())
    return hReturnValue;

  v8::Local<v8::Context> context = pIsolate->GetCurrentContext();
  v8::Local<v8::Value> hException = trycatch->Exception();
  if (hException->IsObject()) {
    v8::Local<v8::String> hNameStr = fxv8::NewStringHelper(pIsolate, "name");
    v8::Local<v8::Value> hValue =
        hException.As<v8::Object>()->Get(context, hNameStr).ToLocalChecked();
    if (hValue->IsString() || hValue->IsStringObject()) {
      hReturnValue->Set(context, 0, hValue).FromJust();
    } else {
      v8::Local<v8::String> hErrorStr =
          fxv8::NewStringHelper(pIsolate, "Error");
      hReturnValue->Set(context, 0, hErrorStr).FromJust();
    }
    v8::Local<v8::String> hMessageStr =
        fxv8::NewStringHelper(pIsolate, "message");
    hValue =
        hException.As<v8::Object>()->Get(context, hMessageStr).ToLocalChecked();
    if (hValue->IsString() || hValue->IsStringObject())
      hReturnValue->Set(context, 1, hValue).FromJust();
    else
      hReturnValue->Set(context, 1, hMessage->Get()).FromJust();
  } else {
    v8::Local<v8::String> hErrorStr = fxv8::NewStringHelper(pIsolate, "Error");
    hReturnValue->Set(context, 0, hErrorStr).FromJust();
    hReturnValue->Set(context, 1, hMessage->Get()).FromJust();
  }
  hReturnValue->Set(context, 2, hException).FromJust();
  int line = hMessage->GetLineNumber(context).FromMaybe(0);
  hReturnValue->Set(context, 3, v8::Integer::New(pIsolate, line)).FromJust();
  v8::Local<v8::String> source =
      hMessage->GetSourceLine(context).FromMaybe(v8::Local<v8::String>());
  hReturnValue->Set(context, 4, source).FromJust();
  int column = hMessage->GetStartColumn(context).FromMaybe(0);
  hReturnValue->Set(context, 5, v8::Integer::New(pIsolate, column)).FromJust();
  column = hMessage->GetEndColumn(context).FromMaybe(0);
  hReturnValue->Set(context, 6, v8::Integer::New(pIsolate, column)).FromJust();
  return hReturnValue;
}

void FXJSE_UpdateProxyBinding(v8::Local<v8::Object> hObject) {
  DCHECK(!hObject.IsEmpty());
  DCHECK_EQ(hObject->InternalFieldCount(), 2);
  hObject->SetAlignedPointerInInternalField(
      0, const_cast<wchar_t*>(kFXJSEProxyObjectTag));
  hObject->SetAlignedPointerInInternalField(1, nullptr);
}

}  // namespace

void FXJSE_UpdateObjectBinding(v8::Local<v8::Object> hObject,
                               CFXJSE_HostObject* pNewBinding) {
  DCHECK(!hObject.IsEmpty());
  DCHECK_EQ(hObject->InternalFieldCount(), 2);
  hObject->SetAlignedPointerInInternalField(
      0, const_cast<wchar_t*>(kFXJSEHostObjectTag));
  hObject->SetAlignedPointerInInternalField(1, pNewBinding);
}

void FXJSE_ClearObjectBinding(v8::Local<v8::Object> hObject) {
  DCHECK(!hObject.IsEmpty());
  DCHECK_EQ(hObject->InternalFieldCount(), 2);
  hObject->SetAlignedPointerInInternalField(0, nullptr);
  hObject->SetAlignedPointerInInternalField(1, nullptr);
}

CFXJSE_HostObject* FXJSE_RetrieveObjectBinding(v8::Local<v8::Value> hValue) {
  if (!fxv8::IsObject(hValue))
    return nullptr;

  v8::Local<v8::Object> hObject = hValue.As<v8::Object>();
  if (hObject->InternalFieldCount() != 2 ||
      hObject->GetAlignedPointerFromInternalField(0) == kFXJSEProxyObjectTag) {
    v8::Local<v8::Value> hProtoObject = hObject->GetPrototype();
    if (!fxv8::IsObject(hProtoObject))
      return nullptr;

    hObject = hProtoObject.As<v8::Object>();
    if (hObject->InternalFieldCount() != 2)
      return nullptr;
  }
  if (hObject->GetAlignedPointerFromInternalField(0) != kFXJSEHostObjectTag)
    return nullptr;

  return static_cast<CFXJSE_HostObject*>(
      hObject->GetAlignedPointerFromInternalField(1));
}

// static
std::unique_ptr<CFXJSE_Context> CFXJSE_Context::Create(
    v8::Isolate* pIsolate,
    const FXJSE_CLASS_DESCRIPTOR* pGlobalClass,
    CFXJSE_HostObject* pGlobalObject,
    CXFA_ThisProxy* pProxy) {
  CFXJSE_ScopeUtil_IsolateHandle scope(pIsolate);

  // Private constructor.
  auto pContext = pdfium::WrapUnique(new CFXJSE_Context(pIsolate, pProxy));
  v8::Local<v8::ObjectTemplate> hObjectTemplate;
  if (pGlobalClass) {
    CFXJSE_Class* pGlobalClassObj =
        CFXJSE_Class::Create(pContext.get(), pGlobalClass, true);
    hObjectTemplate =
        pGlobalClassObj->GetTemplate(pIsolate)->InstanceTemplate();
  } else {
    hObjectTemplate = v8::ObjectTemplate::New(pIsolate);
    hObjectTemplate->SetInternalFieldCount(2);
  }
  hObjectTemplate->Set(v8::Symbol::GetToStringTag(pIsolate),
                       fxv8::NewStringHelper(pIsolate, "global"));

  v8::Local<v8::Context> hNewContext =
      v8::Context::New(pIsolate, nullptr, hObjectTemplate);
  v8::Local<v8::Object> pThisProxy = hNewContext->Global();
  FXJSE_UpdateProxyBinding(pThisProxy);

  v8::Local<v8::Object> pThis = pThisProxy->GetPrototype().As<v8::Object>();
  FXJSE_UpdateObjectBinding(pThis, pGlobalObject);

  v8::Local<v8::Context> hRootContext = v8::Local<v8::Context>::New(
      pIsolate, CFXJSE_RuntimeData::Get(pIsolate)->m_hRootContext);
  hNewContext->SetSecurityToken(hRootContext->GetSecurityToken());
  pContext->m_hContext.Reset(pIsolate, hNewContext);
  return pContext;
}

CFXJSE_Context::CFXJSE_Context(v8::Isolate* pIsolate, CXFA_ThisProxy* pProxy)
    : m_pIsolate(pIsolate), m_pProxy(pProxy) {}

CFXJSE_Context::~CFXJSE_Context() = default;

v8::Local<v8::Object> CFXJSE_Context::GetGlobalObject() {
  v8::Isolate::Scope isolate_scope(GetIsolate());
  v8::EscapableHandleScope handle_scope(GetIsolate());
  v8::Local<v8::Context> hContext =
      v8::Local<v8::Context>::New(GetIsolate(), m_hContext);
  v8::Local<v8::Object> result =
      hContext->Global()->GetPrototype().As<v8::Object>();
  return handle_scope.Escape(result);
}

v8::Local<v8::Context> CFXJSE_Context::GetContext() {
  return v8::Local<v8::Context>::New(GetIsolate(), m_hContext);
}

void CFXJSE_Context::AddClass(std::unique_ptr<CFXJSE_Class> pClass) {
  m_rgClasses.push_back(std::move(pClass));
}

CFXJSE_Class* CFXJSE_Context::GetClassByName(ByteStringView szName) const {
  auto pClass =
      std::find_if(m_rgClasses.begin(), m_rgClasses.end(),
                   [szName](const std::unique_ptr<CFXJSE_Class>& item) {
                     return item->IsName(szName);
                   });
  return pClass != m_rgClasses.end() ? pClass->get() : nullptr;
}

void CFXJSE_Context::EnableCompatibleMode() {
  ExecuteScript(szCompatibleModeScript, nullptr, v8::Local<v8::Object>());
  ExecuteScript(szConsoleScript, nullptr, v8::Local<v8::Object>());
}

bool CFXJSE_Context::ExecuteScript(const char* szScript,
                                   CFXJSE_Value* pRetValue,
                                   v8::Local<v8::Object> hNewThis) {
  CFXJSE_ScopeUtil_IsolateHandleContext scope(this);
  v8::Local<v8::Context> hContext = GetIsolate()->GetCurrentContext();
  v8::TryCatch trycatch(GetIsolate());
  v8::Local<v8::String> hScriptString =
      fxv8::NewStringHelper(GetIsolate(), szScript);
  if (hNewThis.IsEmpty()) {
    v8::Local<v8::Script> hScript;
    if (v8::Script::Compile(hContext, hScriptString).ToLocal(&hScript)) {
      DCHECK(!trycatch.HasCaught());
      v8::Local<v8::Value> hValue;
      if (hScript->Run(hContext).ToLocal(&hValue)) {
        DCHECK(!trycatch.HasCaught());
        if (pRetValue)
          pRetValue->ForceSetValue(GetIsolate(), hValue);
        return true;
      }
    }
    if (pRetValue) {
      pRetValue->ForceSetValue(GetIsolate(),
                               CreateReturnValue(GetIsolate(), &trycatch));
    }
    return false;
  }

  v8::Local<v8::String> hEval = fxv8::NewStringHelper(
      GetIsolate(), "(function () { return eval(arguments[0]); })");
  v8::Local<v8::Script> hWrapper =
      v8::Script::Compile(hContext, hEval).ToLocalChecked();
  v8::Local<v8::Value> hWrapperValue;
  if (hWrapper->Run(hContext).ToLocal(&hWrapperValue)) {
    DCHECK(!trycatch.HasCaught());
    v8::Local<v8::Function> hWrapperFn = hWrapperValue.As<v8::Function>();
    v8::Local<v8::Value> rgArgs[] = {hScriptString};
    v8::Local<v8::Value> hValue;
    if (hWrapperFn->Call(hContext, hNewThis.As<v8::Object>(), 1, rgArgs)
            .ToLocal(&hValue)) {
      DCHECK(!trycatch.HasCaught());
      if (pRetValue)
        pRetValue->ForceSetValue(GetIsolate(), hValue);
      return true;
    }
  }

#ifndef NDEBUG
  v8::String::Utf8Value error(GetIsolate(), trycatch.Exception());
  fprintf(stderr, "JS Error: %s\n", *error);

  v8::Local<v8::Message> message = trycatch.Message();
  if (!message.IsEmpty()) {
    v8::Local<v8::Context> context(GetIsolate()->GetCurrentContext());
    int linenum = message->GetLineNumber(context).FromJust();
    v8::String::Utf8Value sourceline(
        GetIsolate(), message->GetSourceLine(context).ToLocalChecked());
    fprintf(stderr, "Line %d: %s\n", linenum, *sourceline);
  }
#endif  // NDEBUG

  if (pRetValue) {
    pRetValue->ForceSetValue(GetIsolate(),
                             CreateReturnValue(GetIsolate(), &trycatch));
  }
  return false;
}
