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

#include <algorithm>

#include "fpdfsdk/jsapi/include/fxjs_v8.h"
#include "xfa/fxjse/scope_inline.h"

// Duplicates fpdfsdk's cjs_runtime.h, but keeps XFA from depending on it.
// TODO(tsepez): make a single version of this.
class FXJSE_ArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
  void* Allocate(size_t length) override { return calloc(1, length); }
  void* AllocateUninitialized(size_t length) override { return malloc(length); }
  void Free(void* data, size_t length) override { free(data); }
};

static void FXJSE_KillV8() {
  v8::V8::Dispose();
}

void FXJSE_Initialize() {
  if (!CFXJSE_IsolateTracker::g_pInstance)
    CFXJSE_IsolateTracker::g_pInstance = new CFXJSE_IsolateTracker;

  static FX_BOOL bV8Initialized = FALSE;
  if (bV8Initialized)
    return;

  bV8Initialized = TRUE;
  atexit(FXJSE_KillV8);
}

static void FXJSE_Runtime_DisposeCallback(v8::Isolate* pIsolate, bool bOwned) {
  if (FXJS_PerIsolateData* pData = FXJS_PerIsolateData::Get(pIsolate)) {
    delete pData->m_pFXJSERuntimeData;
    pData->m_pFXJSERuntimeData = nullptr;
  }
  if (bOwned)
    pIsolate->Dispose();
}

void FXJSE_Finalize() {
  if (!CFXJSE_IsolateTracker::g_pInstance)
    return;

  CFXJSE_IsolateTracker::g_pInstance->RemoveAll(FXJSE_Runtime_DisposeCallback);
  delete CFXJSE_IsolateTracker::g_pInstance;
  CFXJSE_IsolateTracker::g_pInstance = nullptr;
}

v8::Isolate* FXJSE_Runtime_Create_Own() {
  v8::Isolate::CreateParams params;
  params.array_buffer_allocator = new FXJSE_ArrayBufferAllocator();
  v8::Isolate* pIsolate = v8::Isolate::New(params);
  ASSERT(pIsolate && CFXJSE_IsolateTracker::g_pInstance);
  CFXJSE_IsolateTracker::g_pInstance->Append(pIsolate);
  return pIsolate;
}

void FXJSE_Runtime_Release(v8::Isolate* pIsolate) {
  if (!pIsolate)
    return;
  CFXJSE_IsolateTracker::g_pInstance->Remove(pIsolate,
                                             FXJSE_Runtime_DisposeCallback);
}

CFXJSE_RuntimeData* CFXJSE_RuntimeData::Create(v8::Isolate* pIsolate) {
  CFXJSE_RuntimeData* pRuntimeData = new CFXJSE_RuntimeData(pIsolate);
  CFXJSE_ScopeUtil_IsolateHandle scope(pIsolate);
  v8::Local<v8::FunctionTemplate> hFuncTemplate =
      v8::FunctionTemplate::New(pIsolate);
  v8::Local<v8::Context> hContext =
      v8::Context::New(pIsolate, 0, hFuncTemplate->InstanceTemplate());
  hContext->SetSecurityToken(v8::External::New(pIsolate, pIsolate));
  pRuntimeData->m_hRootContextGlobalTemplate.Reset(pIsolate, hFuncTemplate);
  pRuntimeData->m_hRootContext.Reset(pIsolate, hContext);
  return pRuntimeData;
}

CFXJSE_RuntimeData* CFXJSE_RuntimeData::Get(v8::Isolate* pIsolate) {
  FXJS_PerIsolateData::SetUp(pIsolate);
  FXJS_PerIsolateData* pData = FXJS_PerIsolateData::Get(pIsolate);
  if (!pData->m_pFXJSERuntimeData)
    pData->m_pFXJSERuntimeData = CFXJSE_RuntimeData::Create(pIsolate);
  return pData->m_pFXJSERuntimeData;
}

CFXJSE_IsolateTracker* CFXJSE_IsolateTracker::g_pInstance = nullptr;

void CFXJSE_IsolateTracker::Append(v8::Isolate* pIsolate) {
  m_OwnedIsolates.push_back(pIsolate);
}

void CFXJSE_IsolateTracker::Remove(
    v8::Isolate* pIsolate,
    CFXJSE_IsolateTracker::DisposeCallback lpfnDisposeCallback) {
  auto it = std::find(m_OwnedIsolates.begin(), m_OwnedIsolates.end(), pIsolate);
  bool bFound = it != m_OwnedIsolates.end();
  if (bFound)
    m_OwnedIsolates.erase(it);
  lpfnDisposeCallback(pIsolate, bFound);
}

void CFXJSE_IsolateTracker::RemoveAll(
    CFXJSE_IsolateTracker::DisposeCallback lpfnDisposeCallback) {
  for (v8::Isolate* pIsolate : m_OwnedIsolates)
    lpfnDisposeCallback(pIsolate, true);

  m_OwnedIsolates.clear();
}
