// 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 XFA_FXFA_PARSER_CXFA_SCRIPTCONTEXT_H_
#define XFA_FXFA_PARSER_CXFA_SCRIPTCONTEXT_H_

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

#include "fxjs/cfxjse_arguments.h"
#include "xfa/fxfa/cxfa_eventparam.h"
#include "xfa/fxfa/fm2js/xfa_fm2jscontext.h"
#include "xfa/fxfa/parser/cxfa_document.h"
#include "xfa/fxfa/parser/xfa_resolvenode_rs.h"

#define XFA_RESOLVENODE_TagName 0x0002

class CXFA_ResolveProcessor;

class CXFA_ScriptContext {
 public:
  explicit CXFA_ScriptContext(CXFA_Document* pDocument);
  ~CXFA_ScriptContext();

  void Initialize(v8::Isolate* pIsolate);
  void SetEventParam(CXFA_EventParam param) { m_eventParam = param; }
  CXFA_EventParam* GetEventParam() { return &m_eventParam; }
  bool RunScript(XFA_SCRIPTLANGTYPE eScriptType,
                 const CFX_WideStringC& wsScript,
                 CFXJSE_Value* pRetValue,
                 CXFA_Object* pThisObject);

  int32_t ResolveObjects(CXFA_Object* refObject,
                         const CFX_WideStringC& wsExpression,
                         XFA_RESOLVENODE_RS& resolveNodeRS,
                         uint32_t dwStyles = XFA_RESOLVENODE_Children,
                         CXFA_Node* bindNode = nullptr);
  CFXJSE_Value* GetJSValueFromMap(CXFA_Object* pObject);
  void AddToCacheList(std::unique_ptr<CXFA_NodeList> pList);
  CXFA_Object* GetThisObject() const { return m_pThisObject; }
  v8::Isolate* GetRuntime() const { return m_pIsolate; }

  int32_t GetIndexByName(CXFA_Node* refNode);
  int32_t GetIndexByClassName(CXFA_Node* refNode);
  void GetSomExpression(CXFA_Node* refNode, CFX_WideString& wsExpression);

  void SetNodesOfRunScript(std::vector<CXFA_Node*>* pArray);
  void AddNodesOfRunScript(const std::vector<CXFA_Node*>& nodes);
  void AddNodesOfRunScript(CXFA_Node* pNode);
  CFXJSE_Class* GetJseNormalClass();

  void SetRunAtType(XFA_ATTRIBUTEENUM eRunAt) { m_eRunAtType = eRunAt; }
  bool IsRunAtClient() { return m_eRunAtType != XFA_ATTRIBUTEENUM_Server; }
  bool QueryNodeByFlag(CXFA_Node* refNode,
                       const CFX_WideStringC& propname,
                       CFXJSE_Value* pValue,
                       uint32_t dwFlag,
                       bool bSetting);
  bool QueryVariableValue(CXFA_Node* pScriptNode,
                          const CFX_ByteStringC& szPropName,
                          CFXJSE_Value* pValue,
                          bool bGetter);
  bool QueryBuiltinValue(const CFX_ByteStringC& szPropName,
                         CFXJSE_Value* pValue);
  static void GlobalPropertyGetter(CFXJSE_Value* pObject,
                                   const CFX_ByteStringC& szPropName,
                                   CFXJSE_Value* pValue);
  static void GlobalPropertySetter(CFXJSE_Value* pObject,
                                   const CFX_ByteStringC& szPropName,
                                   CFXJSE_Value* pValue);
  static void NormalPropertyGetter(CFXJSE_Value* pObject,
                                   const CFX_ByteStringC& szPropName,
                                   CFXJSE_Value* pValue);
  static void NormalPropertySetter(CFXJSE_Value* pObject,
                                   const CFX_ByteStringC& szPropName,
                                   CFXJSE_Value* pValue);
  static void NormalMethodCall(CFXJSE_Value* hThis,
                               const CFX_ByteStringC& szFuncName,
                               CFXJSE_Arguments& args);
  static int32_t NormalPropTypeGetter(CFXJSE_Value* pObject,
                                      const CFX_ByteStringC& szPropName,
                                      bool bQueryIn);
  static int32_t GlobalPropTypeGetter(CFXJSE_Value* pObject,
                                      const CFX_ByteStringC& szPropName,
                                      bool bQueryIn);
  bool RunVariablesScript(CXFA_Node* pScriptNode);
  CXFA_Object* GetVariablesThis(CXFA_Object* pObject, bool bScriptNode = false);
  bool IsStrictScopeInJavaScript();
  XFA_SCRIPTLANGTYPE GetType();
  std::vector<CXFA_Node*>* GetUpObjectArray() { return &m_upObjectArray; }
  CXFA_Document* GetDocument() const { return m_pDocument; }

  static CXFA_Object* ToObject(CFXJSE_Value* pValue, CFXJSE_Class* pClass);

 private:
  void DefineJsContext();
  CFXJSE_Context* CreateVariablesContext(CXFA_Node* pScriptNode,
                                         CXFA_Node* pSubform);
  void DefineJsClass();
  void RemoveBuiltInObjs(CFXJSE_Context* pContext) const;

  CXFA_Document* m_pDocument;
  std::unique_ptr<CFXJSE_Context> m_JsContext;
  v8::Isolate* m_pIsolate;
  CFXJSE_Class* m_pJsClass;
  XFA_SCRIPTLANGTYPE m_eScriptType;
  std::map<CXFA_Object*, std::unique_ptr<CFXJSE_Value>> m_mapObjectToValue;
  std::map<CXFA_Object*, CFXJSE_Context*> m_mapVariableToContext;
  CXFA_EventParam m_eventParam;
  std::vector<CXFA_Node*> m_upObjectArray;
  // CacheList holds the NodeList items so we can clean them up when we're done.
  std::vector<std::unique_ptr<CXFA_NodeList>> m_CacheList;
  std::vector<CXFA_Node*>* m_pScriptNodeArray;
  std::unique_ptr<CXFA_ResolveProcessor> m_ResolveProcessor;
  std::unique_ptr<CXFA_FM2JSContext> m_FM2JSContext;
  CXFA_Object* m_pThisObject;
  uint32_t m_dwBuiltInInFlags;
  XFA_ATTRIBUTEENUM m_eRunAtType;
};

#endif  //  XFA_FXFA_PARSER_CXFA_SCRIPTCONTEXT_H_
