// 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

// CFXJS_ENGINE is a layer that makes it easier to define native objects in V8,
// but has no knowledge of PDF-specific native objects. It could in theory be
// used to implement other sets of native objects.

// PDFium code should include this file rather than including V8 headers
// directly.

#ifndef FXJS_CFXJS_ENGINE_H_
#define FXJS_CFXJS_ENGINE_H_

#include <functional>
#include <map>
#include <memory>
#include <vector>

#include "core/fxcrt/fx_string.h"
#include "fxjs/cfx_v8.h"
#include "fxjs/ijs_runtime.h"
#include "v8/include/v8-util.h"
#include "v8/include/v8.h"

#ifdef PDF_ENABLE_XFA
// CFXJS_ENGINE doesn't interpret this class, it is just passed along to XFA.
class CFXJSE_RuntimeData;
#endif  // PDF_ENABLE_XFA

class CFXJS_ObjDefinition;
class CJS_Object;
class V8TemplateMap;

// CFXJS_ENGINE places no restrictions on this class; it merely passes it
// on to caller-provided methods.
class IJS_EventContext;  // A description of the event that caused JS execution.

enum FXJSOBJTYPE {
  FXJSOBJTYPE_DYNAMIC = 0,  // Created by native method and returned to JS.
  FXJSOBJTYPE_STATIC,       // Created by init and hung off of global object.
  FXJSOBJTYPE_GLOBAL,       // The global object itself (may only appear once).
};

class FXJS_PerIsolateData {
 public:
  ~FXJS_PerIsolateData();

  static void SetUp(v8::Isolate* pIsolate);
  static FXJS_PerIsolateData* Get(v8::Isolate* pIsolate);

  std::vector<std::unique_ptr<CFXJS_ObjDefinition>> m_ObjectDefnArray;
#ifdef PDF_ENABLE_XFA
  std::unique_ptr<CFXJSE_RuntimeData> m_pFXJSERuntimeData;
#endif  // PDF_ENABLE_XFA
  std::unique_ptr<V8TemplateMap> m_pDynamicObjsMap;

 protected:
  explicit FXJS_PerIsolateData(v8::Isolate* pIsolate);
};

void FXJS_Initialize(unsigned int embedderDataSlot, v8::Isolate* pIsolate);
void FXJS_Release();

// Gets the global isolate set by FXJS_Initialize(), or makes a new one each
// time if there is no such isolate. Returns true if a new isolate had to be
// created.
bool FXJS_GetIsolate(v8::Isolate** pResultIsolate);

// Get the global isolate's ref count.
size_t FXJS_GlobalIsolateRefCount();

class CFXJS_Engine : public CFX_V8 {
 public:
  explicit CFXJS_Engine(v8::Isolate* pIsolate);
  ~CFXJS_Engine() override;

  using Constructor =
      std::function<void(CFXJS_Engine* pEngine, v8::Local<v8::Object> obj)>;
  using Destructor = std::function<void(v8::Local<v8::Object> obj)>;

  static CFXJS_Engine* EngineFromIsolateCurrentContext(v8::Isolate* pIsolate);
  static CFXJS_Engine* EngineFromContext(v8::Local<v8::Context> pContext);

  static int GetObjDefnID(v8::Local<v8::Object> pObj);

  static void SetObjectPrivate(v8::Local<v8::Object> pObj,
                               std::unique_ptr<CJS_Object> p);
  static void FreeObjectPrivate(v8::Local<v8::Object> pObj);

  void SetIntoContext(v8::Local<v8::Context> pContext);

  // Always returns a valid, newly-created objDefnID.
  int DefineObj(const char* sObjName,
                FXJSOBJTYPE eObjType,
                Constructor pConstructor,
                Destructor pDestructor);

  void DefineObjMethod(int nObjDefnID,
                       const char* sMethodName,
                       v8::FunctionCallback pMethodCall);
  void DefineObjProperty(int nObjDefnID,
                         const char* sPropName,
                         v8::AccessorGetterCallback pPropGet,
                         v8::AccessorSetterCallback pPropPut);
  void DefineObjAllProperties(int nObjDefnID,
                              v8::GenericNamedPropertyQueryCallback pPropQurey,
                              v8::GenericNamedPropertyGetterCallback pPropGet,
                              v8::GenericNamedPropertySetterCallback pPropPut,
                              v8::GenericNamedPropertyDeleterCallback pPropDel);
  void DefineObjConst(int nObjDefnID,
                      const char* sConstName,
                      v8::Local<v8::Value> pDefault);
  void DefineGlobalMethod(const char* sMethodName,
                          v8::FunctionCallback pMethodCall);
  void DefineGlobalConst(const wchar_t* sConstName,
                         v8::FunctionCallback pConstGetter);

  // Called after FXJS_Define* calls made.
  void InitializeEngine();
  void ReleaseEngine();

  // Called after FXJS_InitializeEngine call made.
  Optional<IJS_Runtime::JS_Error> Execute(const WideString& script);

  v8::Local<v8::Object> GetThisObj();
  v8::Local<v8::Object> NewFXJSBoundObject(int nObjDefnID,
                                           bool bStatic = false);
  // Retrieve native object binding.
  CJS_Object* GetObjectPrivate(v8::Local<v8::Object> pObj);

  void Error(const WideString& message);

  v8::Local<v8::Context> GetV8Context() {
    return v8::Local<v8::Context>::New(GetIsolate(), m_V8Context);
  }

  v8::Local<v8::Array> GetConstArray(const WideString& name);
  void SetConstArray(const WideString& name, v8::Local<v8::Array> array);

 protected:
  CFXJS_Engine();

 private:
  v8::Global<v8::Context> m_V8Context;
  std::vector<v8::Global<v8::Object>> m_StaticObjects;
  std::map<WideString, v8::Global<v8::Array>> m_ConstArrays;
};

#endif  // FXJS_CFXJS_ENGINE_H_
