// 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 "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 = NULL;
void CFXJSE_RuntimeList::AppendRuntime(v8::Isolate* pIsolate) {
  m_RuntimeList.Add(pIsolate);
}

void CFXJSE_RuntimeList::RemoveRuntime(
    v8::Isolate* pIsolate,
    CFXJSE_RuntimeList::RuntimeDisposeCallback lpfnDisposeCallback) {
  int32_t iIdx = m_RuntimeList.Find(pIsolate, 0);
  if (iIdx >= 0) {
    m_RuntimeList.RemoveAt(iIdx, 1);
  }
  if (lpfnDisposeCallback) {
    lpfnDisposeCallback(pIsolate);
  }
}

void CFXJSE_RuntimeList::RemoveAllRuntimes(
    CFXJSE_RuntimeList::RuntimeDisposeCallback lpfnDisposeCallback) {
  int32_t iSize = m_RuntimeList.GetSize();
  if (lpfnDisposeCallback) {
    for (int32_t iIdx = 0; iIdx < iSize; iIdx++) {
      lpfnDisposeCallback(m_RuntimeList[iIdx]);
    }
  }
  m_RuntimeList.RemoveAll();
}
