// 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_RuntimeData::g_RuntimeList) {
    CFXJSE_RuntimeData::g_RuntimeList = new CFXJSE_RuntimeList;
  }
  static FX_BOOL bV8Initialized = FALSE;
  if (bV8Initialized) {
    return;
  }
  bV8Initialized = TRUE;
  atexit(FXJSE_KillV8);
}

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

void FXJSE_Finalize() {
  if (CFXJSE_RuntimeData::g_RuntimeList) {
    CFXJSE_RuntimeData::g_RuntimeList->RemoveAllRuntimes(
        FXJSE_Runtime_DisposeCallback);
    delete CFXJSE_RuntimeData::g_RuntimeList;
    CFXJSE_RuntimeData::g_RuntimeList = NULL;
  }
}

FXJSE_HRUNTIME FXJSE_Runtime_Create() {
  v8::Isolate::CreateParams params;
  params.array_buffer_allocator = new FXJSE_ArrayBufferAllocator();
  v8::Isolate* pIsolate = v8::Isolate::New(params);
  ASSERT(pIsolate && CFXJSE_RuntimeData::g_RuntimeList);
  CFXJSE_RuntimeData::g_RuntimeList->AppendRuntime(pIsolate);
  return reinterpret_cast<FXJSE_HRUNTIME>(pIsolate);
}

void FXJSE_Runtime_Release(FXJSE_HRUNTIME hRuntime, bool bOwnedRuntime) {
  v8::Isolate* pIsolate = reinterpret_cast<v8::Isolate*>(hRuntime);
  if (!pIsolate)
    return;
  if (bOwnedRuntime) {
    ASSERT(CFXJSE_RuntimeData::g_RuntimeList);
    CFXJSE_RuntimeData::g_RuntimeList->RemoveRuntime(
        pIsolate, FXJSE_Runtime_DisposeCallback);
  } else {
    if (FXJS_PerIsolateData* pData = FXJS_PerIsolateData::Get(pIsolate)) {
      delete pData->m_pFXJSERuntimeData;
      pData->m_pFXJSERuntimeData = nullptr;
    }
  }
}

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_RuntimeList* CFXJSE_RuntimeData::g_RuntimeList = nullptr;

void CFXJSE_RuntimeList::AppendRuntime(v8::Isolate* pIsolate) {
  m_RuntimeList.push_back(pIsolate);
}

void CFXJSE_RuntimeList::RemoveRuntime(
    v8::Isolate* pIsolate,
    CFXJSE_RuntimeList::RuntimeDisposeCallback lpfnDisposeCallback) {
  auto it = std::find(m_RuntimeList.begin(), m_RuntimeList.end(), pIsolate);
  if (it != m_RuntimeList.end())
    m_RuntimeList.erase(it);
  if (lpfnDisposeCallback)
    lpfnDisposeCallback(pIsolate);
}

void CFXJSE_RuntimeList::RemoveAllRuntimes(
    CFXJSE_RuntimeList::RuntimeDisposeCallback lpfnDisposeCallback) {
  if (lpfnDisposeCallback) {
    for (v8::Isolate* pIsolate : m_RuntimeList)
      lpfnDisposeCallback(pIsolate);
  }
  m_RuntimeList.clear();
}
