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

#ifndef FXJS_CJS_GLOBAL_H_
#define FXJS_CJS_GLOBAL_H_

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

#include "core/fxcrt/unowned_ptr.h"
#include "fxjs/cfx_keyvalue.h"
#include "fxjs/cjs_object.h"
#include "fxjs/cjs_result.h"

class CFX_GlobalData;

// The CJS_Global object is not the V8 global object (i.e. it is not |this|
// in JavaScript outside of a bound function call). It is a facility for
// sharing data amongst documents and persisting data within a document
// between sessions. It is only partially implemented due to security and
// privacy concerns. It provides access via properties in the usual manner,
// execpt that these are stored on the C++ side rather than in V8 itself.
// It is a static object that is available as "global" property of the V8
// global object and can be manipulated from JavaScript as |global['foo']|
// for example.

class CJS_Global final : public CJS_Object {
 public:
  static uint32_t GetObjDefnID();
  static void DefineJSObjects(CFXJS_Engine* pEngine);
  static void DefineAllProperties(CFXJS_Engine* pEngine);

  static void queryprop_static(
      v8::Local<v8::Name> property,
      const v8::PropertyCallbackInfo<v8::Integer>& info);
  static void getprop_static(v8::Local<v8::Name> property,
                             const v8::PropertyCallbackInfo<v8::Value>& info);
  static void putprop_static(v8::Local<v8::Name> property,
                             v8::Local<v8::Value> value,
                             const v8::PropertyCallbackInfo<v8::Value>& info);
  static void delprop_static(v8::Local<v8::Name> property,
                             const v8::PropertyCallbackInfo<v8::Boolean>& info);
  static void enumprop_static(const v8::PropertyCallbackInfo<v8::Array>& info);

  static void setPersistent_static(
      const v8::FunctionCallbackInfo<v8::Value>& info);

  CJS_Global(v8::Local<v8::Object> pObject, CJS_Runtime* pRuntime);
  ~CJS_Global() override;

  CJS_Result setPersistent(CJS_Runtime* pRuntime,
                           const std::vector<v8::Local<v8::Value>>& params);
  bool HasProperty(const WideString& propname);
  bool DelProperty(CJS_Runtime* pRuntime, const WideString& propname);
  CJS_Result GetProperty(CJS_Runtime* pRuntime, const WideString& propname);
  CJS_Result SetProperty(CJS_Runtime* pRuntime,
                         const WideString& propname,
                         v8::Local<v8::Value> vp);
  void EnumProperties(CJS_Runtime* pRuntime,
                      const v8::PropertyCallbackInfo<v8::Array>& info);

 private:
  struct JSGlobalData : public CFX_Value {
   public:
    JSGlobalData();
    ~JSGlobalData();

    v8::Global<v8::Object> pData;
    bool bPersistent = false;
    bool bDeleted = false;
  };

  static uint32_t ObjDefnID;
  static const JSMethodSpec MethodSpecs[];

  void UpdateGlobalPersistentVariables();
  // TODO(crbug.com/pdfium/926): This method is never called.
  void CommitGlobalPersisitentVariables();
  void DestroyGlobalPersisitentVariables();
  CJS_Result SetGlobalVariables(const ByteString& propname,
                                CFX_Value::DataType nType,
                                double dData,
                                bool bData,
                                const ByteString& sData,
                                v8::Local<v8::Object> pData,
                                bool bDefaultPersistent);
  std::vector<std::unique_ptr<CFX_KeyValue>> ObjectToArray(
      CJS_Runtime* pRuntime,
      v8::Local<v8::Object> pObj);
  void PutObjectProperty(v8::Local<v8::Object> obj, CFX_KeyValue* pData);

  std::map<ByteString, std::unique_ptr<JSGlobalData>> m_MapGlobal;
  UnownedPtr<CFX_GlobalData> m_pGlobalData;
};

#endif  // FXJS_CJS_GLOBAL_H_
