// Copyright 2014 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 "xfa/fxjse/context.h"

#include "xfa/fxjse/class.h"
#include "xfa/fxjse/scope_inline.h"
#include "xfa/fxjse/util_inline.h"
#include "xfa/fxjse/value.h"

CFXJSE_Context* FXJSE_Context_Create(
    v8::Isolate* pIsolate,
    const FXJSE_CLASS_DESCRIPTOR* lpGlobalClass,
    void* lpGlobalObject) {
  return CFXJSE_Context::Create(pIsolate, lpGlobalClass, lpGlobalObject);
}

void FXJSE_Context_Release(CFXJSE_Context* pContext) {
  delete pContext;
}

CFXJSE_Value* FXJSE_Context_GetGlobalObject(CFXJSE_Context* pContext) {
  if (!pContext)
    return nullptr;

  CFXJSE_Value* lpValue = CFXJSE_Value::Create(pContext->GetRuntime());
  ASSERT(lpValue);
  pContext->GetGlobalObject(lpValue);
  return lpValue;
}

static const FX_CHAR* szCompatibleModeScripts[] = {
    "(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']}));"};
void FXJSE_Context_EnableCompatibleMode(CFXJSE_Context* pContext,
                                        uint32_t dwCompatibleFlags) {
  for (uint32_t i = 0; i < (uint32_t)FXJSE_COMPATIBLEMODEFLAGCOUNT; i++) {
    if (dwCompatibleFlags & (1 << i)) {
      FXJSE_ExecuteScript(pContext, szCompatibleModeScripts[i], NULL, NULL);
    }
  }
}

FX_BOOL FXJSE_ExecuteScript(CFXJSE_Context* pContext,
                            const FX_CHAR* szScript,
                            CFXJSE_Value* pRetValue,
                            CFXJSE_Value* pNewThisObject) {
  return pContext->ExecuteScript(szScript, pRetValue, pNewThisObject);
}

v8::Local<v8::Object> FXJSE_CreateReturnValue(v8::Isolate* pIsolate,
                                              v8::TryCatch& trycatch) {
  v8::Local<v8::Object> hReturnValue = v8::Object::New(pIsolate);
  if (trycatch.HasCaught()) {
    v8::Local<v8::Value> hException = trycatch.Exception();
    v8::Local<v8::Message> hMessage = trycatch.Message();
    if (hException->IsObject()) {
      v8::Local<v8::Value> hValue;
      hValue = hException.As<v8::Object>()->Get(
          v8::String::NewFromUtf8(pIsolate, "name"));
      if (hValue->IsString() || hValue->IsStringObject()) {
        hReturnValue->Set(0, hValue);
      } else {
        hReturnValue->Set(0, v8::String::NewFromUtf8(pIsolate, "Error"));
      }
      hValue = hException.As<v8::Object>()->Get(
          v8::String::NewFromUtf8(pIsolate, "message"));
      if (hValue->IsString() || hValue->IsStringObject()) {
        hReturnValue->Set(1, hValue);
      } else {
        hReturnValue->Set(1, hMessage->Get());
      }
    } else {
      hReturnValue->Set(0, v8::String::NewFromUtf8(pIsolate, "Error"));
      hReturnValue->Set(1, hMessage->Get());
    }
    hReturnValue->Set(2, hException);
    hReturnValue->Set(3, v8::Integer::New(pIsolate, hMessage->GetLineNumber()));
    hReturnValue->Set(4, hMessage->GetSourceLine());
    v8::Maybe<int32_t> maybe_int =
        hMessage->GetStartColumn(pIsolate->GetCurrentContext());
    hReturnValue->Set(5, v8::Integer::New(pIsolate, maybe_int.FromMaybe(0)));
    maybe_int = hMessage->GetEndColumn(pIsolate->GetCurrentContext());
    hReturnValue->Set(6, v8::Integer::New(pIsolate, maybe_int.FromMaybe(0)));
  }
  return hReturnValue;
}

CFXJSE_Context* CFXJSE_Context::Create(
    v8::Isolate* pIsolate,
    const FXJSE_CLASS_DESCRIPTOR* lpGlobalClass,
    void* lpGlobalObject) {
  CFXJSE_ScopeUtil_IsolateHandle scope(pIsolate);
  CFXJSE_Context* pContext = new CFXJSE_Context(pIsolate);
  CFXJSE_Class* lpGlobalClassObj = NULL;
  v8::Local<v8::ObjectTemplate> hObjectTemplate;
  if (lpGlobalClass) {
    lpGlobalClassObj = CFXJSE_Class::Create(pContext, lpGlobalClass, TRUE);
    ASSERT(lpGlobalClassObj);
    v8::Local<v8::FunctionTemplate> hFunctionTemplate =
        v8::Local<v8::FunctionTemplate>::New(pIsolate,
                                             lpGlobalClassObj->m_hTemplate);
    hObjectTemplate = hFunctionTemplate->InstanceTemplate();
  } else {
    hObjectTemplate = v8::ObjectTemplate::New(pIsolate);
    hObjectTemplate->SetInternalFieldCount(1);
  }
  v8::Local<v8::Context> hNewContext =
      v8::Context::New(pIsolate, NULL, hObjectTemplate);
  v8::Local<v8::Context> hRootContext = v8::Local<v8::Context>::New(
      pIsolate, CFXJSE_RuntimeData::Get(pIsolate)->m_hRootContext);
  hNewContext->SetSecurityToken(hRootContext->GetSecurityToken());
  v8::Local<v8::Object> hGlobalObject =
      FXJSE_GetGlobalObjectFromContext(hNewContext);
  FXJSE_UpdateObjectBinding(hGlobalObject, lpGlobalObject);
  pContext->m_hContext.Reset(pIsolate, hNewContext);
  return pContext;
}

CFXJSE_Context::CFXJSE_Context(v8::Isolate* pIsolate) : m_pIsolate(pIsolate) {}
CFXJSE_Context::~CFXJSE_Context() {}

void CFXJSE_Context::GetGlobalObject(CFXJSE_Value* pValue) {
  ASSERT(pValue);
  CFXJSE_ScopeUtil_IsolateHandleContext scope(this);
  v8::Local<v8::Context> hContext =
      v8::Local<v8::Context>::New(m_pIsolate, m_hContext);
  v8::Local<v8::Object> hGlobalObject = hContext->Global();
  pValue->ForceSetValue(hGlobalObject);
}

FX_BOOL CFXJSE_Context::ExecuteScript(const FX_CHAR* szScript,
                                      CFXJSE_Value* lpRetValue,
                                      CFXJSE_Value* lpNewThisObject) {
  CFXJSE_ScopeUtil_IsolateHandleContext scope(this);
  v8::TryCatch trycatch(m_pIsolate);
  v8::Local<v8::String> hScriptString =
      v8::String::NewFromUtf8(m_pIsolate, szScript);
  if (lpNewThisObject == NULL) {
    v8::Local<v8::Script> hScript = v8::Script::Compile(hScriptString);
    if (!trycatch.HasCaught()) {
      v8::Local<v8::Value> hValue = hScript->Run();
      if (!trycatch.HasCaught()) {
        if (lpRetValue) {
          lpRetValue->m_hValue.Reset(m_pIsolate, hValue);
        }
        return TRUE;
      }
    }
    if (lpRetValue) {
      lpRetValue->m_hValue.Reset(m_pIsolate,
                                 FXJSE_CreateReturnValue(m_pIsolate, trycatch));
    }
    return FALSE;
  } else {
    v8::Local<v8::Value> hNewThis =
        v8::Local<v8::Value>::New(m_pIsolate, lpNewThisObject->m_hValue);
    ASSERT(!hNewThis.IsEmpty());
    v8::Local<v8::Script> hWrapper =
        v8::Script::Compile(v8::String::NewFromUtf8(
            m_pIsolate, "(function () { return eval(arguments[0]); })"));
    v8::Local<v8::Value> hWrapperValue = hWrapper->Run();
    ASSERT(hWrapperValue->IsFunction());
    v8::Local<v8::Function> hWrapperFn = hWrapperValue.As<v8::Function>();
    if (!trycatch.HasCaught()) {
      v8::Local<v8::Value> rgArgs[] = {hScriptString};
      v8::Local<v8::Value> hValue =
          hWrapperFn->Call(hNewThis.As<v8::Object>(), 1, rgArgs);
      if (!trycatch.HasCaught()) {
        if (lpRetValue) {
          lpRetValue->m_hValue.Reset(m_pIsolate, hValue);
        }
        return TRUE;
      }
    }
    if (lpRetValue) {
      lpRetValue->m_hValue.Reset(m_pIsolate,
                                 FXJSE_CreateReturnValue(m_pIsolate, trycatch));
    }
    return FALSE;
  }
}
