// Copyright 2014 The PDFium Authors
// 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/cjs_runtime.h"

#include <math.h>

#include <algorithm>

#include "core/fxcrt/check_op.h"
#include "fpdfsdk/cpdfsdk_formfillenvironment.h"
#include "fxjs/cfx_globaldata.h"
#include "fxjs/cjs_annot.h"
#include "fxjs/cjs_app.h"
#include "fxjs/cjs_border.h"
#include "fxjs/cjs_color.h"
#include "fxjs/cjs_console.h"
#include "fxjs/cjs_display.h"
#include "fxjs/cjs_document.h"
#include "fxjs/cjs_event.h"
#include "fxjs/cjs_event_context.h"
#include "fxjs/cjs_field.h"
#include "fxjs/cjs_font.h"
#include "fxjs/cjs_global.h"
#include "fxjs/cjs_globalarrays.h"
#include "fxjs/cjs_globalconsts.h"
#include "fxjs/cjs_highlight.h"
#include "fxjs/cjs_icon.h"
#include "fxjs/cjs_object.h"
#include "fxjs/cjs_position.h"
#include "fxjs/cjs_publicmethods.h"
#include "fxjs/cjs_scalehow.h"
#include "fxjs/cjs_scalewhen.h"
#include "fxjs/cjs_style.h"
#include "fxjs/cjs_timerobj.h"
#include "fxjs/cjs_util.h"
#include "fxjs/cjs_zoomtype.h"
#include "fxjs/fxv8.h"
#include "fxjs/js_define.h"
#include "v8/include/v8-context.h"
#include "v8/include/v8-exception.h"
#include "v8/include/v8-isolate.h"

CJS_Runtime::CJS_Runtime(CPDFSDK_FormFillEnvironment* pFormFillEnv)
    : form_fill_env_(pFormFillEnv) {
  v8::Isolate* pIsolate = nullptr;
  IPDF_JSPLATFORM* pPlatform = form_fill_env_->GetJSPlatform();
  if (pPlatform->version <= 2) {
    // Backwards compatibility - JS now initialized earlier in more modern
    // JSPLATFORM versions.
    unsigned int embedderDataSlot = 0;
    v8::Isolate* pExternalIsolate = nullptr;
    if (pPlatform->version == 2) {
      pExternalIsolate = static_cast<v8::Isolate*>(pPlatform->m_isolate);
      embedderDataSlot = pPlatform->m_v8EmbedderSlot;
    }
    FXJS_Initialize(embedderDataSlot, pExternalIsolate);
  }
  isolate_managed_ = FXJS_GetIsolate(&pIsolate);
  SetIsolate(pIsolate);

  v8::Isolate::Scope isolate_scope(pIsolate);
  v8::HandleScope handle_scope(pIsolate);
  if (isolate_managed_ || FXJS_GlobalIsolateRefCount() == 0) {
    DefineJSObjects();
  }

  ScopedEventContext context(this);
  InitializeEngine();
  SetFormFillEnvToDocument();
}

CJS_Runtime::~CJS_Runtime() {
  NotifyObservers();
  ReleaseEngine();
  if (isolate_managed_) {
    DisposeIsolate();
  }
}

void CJS_Runtime::DefineJSObjects() {
  v8::Isolate::Scope isolate_scope(GetIsolate());
  v8::HandleScope handle_scope(GetIsolate());
  v8::Local<v8::Context> context = v8::Context::New(GetIsolate());
  v8::Context::Scope context_scope(context);

  // The call order determines the "ObjDefID" assigned to each class.
  // ObjDefIDs 0 - 2
  CJS_Border::DefineJSObjects(this);
  CJS_Display::DefineJSObjects(this);
  CJS_Font::DefineJSObjects(this);

  // ObjDefIDs 3 - 5
  CJS_Highlight::DefineJSObjects(this);
  CJS_Position::DefineJSObjects(this);
  CJS_ScaleHow::DefineJSObjects(this);

  // ObjDefIDs 6 - 8
  CJS_ScaleWhen::DefineJSObjects(this);
  CJS_Style::DefineJSObjects(this);
  CJS_Zoomtype::DefineJSObjects(this);

  // ObjDefIDs 9 - 11
  CJS_App::DefineJSObjects(this);
  CJS_Color::DefineJSObjects(this);
  CJS_Console::DefineJSObjects(this);

  // ObjDefIDs 12 - 14
  CJS_Document::DefineJSObjects(this);
  CJS_Event::DefineJSObjects(this);
  CJS_Field::DefineJSObjects(this);

  // ObjDefIDs 15 - 17
  CJS_Global::DefineJSObjects(this);
  CJS_Icon::DefineJSObjects(this);
  CJS_Util::DefineJSObjects(this);

  // ObjDefIDs 18 - 20 (these can't fail, return void).
  CJS_PublicMethods::DefineJSObjects(this);
  CJS_GlobalConsts::DefineJSObjects(this);
  CJS_GlobalArrays::DefineJSObjects(this);

  // ObjDefIDs 21 - 22.
  CJS_TimerObj::DefineJSObjects(this);
  CJS_Annot::DefineJSObjects(this);
}

IJS_EventContext* CJS_Runtime::NewEventContext() {
  event_context_array_.push_back(std::make_unique<CJS_EventContext>(this));
  return event_context_array_.back().get();
}

void CJS_Runtime::ReleaseEventContext(IJS_EventContext* context) {
  DCHECK_EQ(context, event_context_array_.back().get());
  event_context_array_.pop_back();
}

CJS_EventContext* CJS_Runtime::GetCurrentEventContext() const {
  return event_context_array_.empty() ? nullptr
                                      : event_context_array_.back().get();
}

CFX_Timer::HandlerIface* CJS_Runtime::GetTimerHandler() const {
  return form_fill_env_ ? form_fill_env_->GetTimerHandler() : nullptr;
}

void CJS_Runtime::SetFormFillEnvToDocument() {
  v8::Isolate::Scope isolate_scope(GetIsolate());
  v8::HandleScope handle_scope(GetIsolate());
  v8::Local<v8::Context> context = GetV8Context();
  v8::Context::Scope context_scope(context);

  v8::Local<v8::Object> pThis = GetThisObj();
  if (pThis.IsEmpty()) {
    return;
  }

  auto pJSDocument = JSGetObject<CJS_Document>(pThis);
  if (!pJSDocument) {
    return;
  }

  pJSDocument->SetFormFillEnv(form_fill_env_.Get());
}

CPDFSDK_FormFillEnvironment* CJS_Runtime::GetFormFillEnv() const {
  return form_fill_env_.Get();
}

std::optional<IJS_Runtime::JS_Error> CJS_Runtime::ExecuteScript(
    const WideString& script) {
  return Execute(script);
}

bool CJS_Runtime::AddEventToSet(const FieldEvent& event) {
  return field_event_set_.insert(event).second;
}

void CJS_Runtime::RemoveEventFromSet(const FieldEvent& event) {
  field_event_set_.erase(event);
}

CJS_Runtime* CJS_Runtime::AsCJSRuntime() {
  return this;
}

v8::Local<v8::Value> CJS_Runtime::GetValueByNameFromGlobalObject(
    ByteStringView utf8Name) {
  v8::Isolate::Scope isolate_scope(GetIsolate());
  v8::Local<v8::Context> context = GetV8Context();
  v8::Context::Scope context_scope(context);
  v8::Local<v8::String> str = fxv8::NewStringHelper(GetIsolate(), utf8Name);
  v8::MaybeLocal<v8::Value> maybe_value = context->Global()->Get(context, str);
  if (maybe_value.IsEmpty()) {
    return v8::Local<v8::Value>();
  }
  return maybe_value.ToLocalChecked();
}

bool CJS_Runtime::SetValueByNameInGlobalObject(ByteStringView utf8Name,
                                               v8::Local<v8::Value> pValue) {
  if (utf8Name.IsEmpty() || pValue.IsEmpty()) {
    return false;
  }

  v8::Isolate* pIsolate = GetIsolate();
  v8::Isolate::Scope isolate_scope(pIsolate);
  v8::Local<v8::Context> context = GetV8Context();
  v8::Context::Scope context_scope(context);
  v8::Local<v8::String> str = fxv8::NewStringHelper(pIsolate, utf8Name);
  v8::Maybe<bool> result = context->Global()->Set(context, str, pValue);
  return result.IsJust() && result.FromJust();
}

v8::Local<v8::Value> CJS_Runtime::MaybeCoerceToNumber(
    v8::Local<v8::Value> value) {
  bool bAllowNaN = false;
  if (value->IsString()) {
    ByteString bstr = fxv8::ToByteString(GetIsolate(), value.As<v8::String>());
    if (bstr.IsEmpty()) {
      return value;
    }
    if (bstr == "NaN") {
      bAllowNaN = true;
    }
  }

  v8::TryCatch try_catch(GetIsolate());
  v8::MaybeLocal<v8::Number> maybeNum =
      value->ToNumber(GetIsolate()->GetCurrentContext());
  if (maybeNum.IsEmpty()) {
    return value;
  }

  v8::Local<v8::Number> num = maybeNum.ToLocalChecked();
  if (isnan(num->Value()) && !bAllowNaN) {
    return value;
  }

  return num;
}
