// 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) {
  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;
  }
}

v8::Isolate* 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 pIsolate;
}

void FXJSE_Runtime_Release(v8::Isolate* pIsolate, bool bOwnedRuntime) {
  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();
}
