// 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/widestring.h"
#include "fxjs/cfx_v8.h"
#include "fxjs/ijs_runtime.h"
#include "v8/include/v8-forward.h"
#include "v8/include/v8-function-callback.h"
#include "v8/include/v8-persistent-handle.h"
#include "v8/include/v8-template.h"

class CFXJS_ObjDefinition;
class CJS_Object;
class V8TemplateMap;

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:
  // Hook for XFA's data, when present.
  class ExtensionIface {
   public:
    virtual ~ExtensionIface() = default;
  };

  ~FXJS_PerIsolateData();

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

  uint32_t CurrentMaxObjDefinitionID() const;
  CFXJS_ObjDefinition* ObjDefinitionForID(uint32_t id) const;
  uint32_t AssignIDForObjDefinition(std::unique_ptr<CFXJS_ObjDefinition> pDefn);

  const wchar_t* const m_Tag;  // Raw, always a literal.
  std::vector<std::unique_ptr<CFXJS_ObjDefinition>> m_ObjectDefnArray;
  std::unique_ptr<V8TemplateMap> m_pDynamicObjsMap;
  std::unique_ptr<ExtensionIface> m_pFXJSERuntimeData;

 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 uint32_t GetObjDefnID(v8::Local<v8::Object> pObj);
  static CJS_Object* GetObjectPrivate(v8::Isolate* pIsolate,
                                      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);

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

  void DefineObjMethod(uint32_t nObjDefnID,
                       const char* sMethodName,
                       v8::FunctionCallback pMethodCall);
  void DefineObjProperty(uint32_t nObjDefnID,
                         const char* sPropName,
                         v8::AccessorGetterCallback pPropGet,
                         v8::AccessorSetterCallback pPropPut);
  void DefineObjAllProperties(uint32_t nObjDefnID,
                              v8::GenericNamedPropertyQueryCallback pPropQurey,
                              v8::GenericNamedPropertyGetterCallback pPropGet,
                              v8::GenericNamedPropertySetterCallback pPropPut,
                              v8::GenericNamedPropertyDeleterCallback pPropDel);
  void DefineObjConst(uint32_t 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.
  absl::optional<IJS_Runtime::JS_Error> Execute(const WideString& script);

  v8::Local<v8::Object> GetThisObj();
  v8::Local<v8::Object> NewFXJSBoundObject(uint32_t nObjDefnID,
                                           FXJSOBJTYPE type);
  void Error(const WideString& message);

  v8::Local<v8::Context> GetV8Context();

  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_
