// 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_DOCUMENT_H_
#define XFA_FXFA_PARSER_CXFA_DOCUMENT_H_

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

#include "core/fxcrt/fx_system.h"
#include "core/fxcrt/unowned_ptr.h"
#include "fxjs/gc/heap.h"
#include "third_party/base/optional.h"
#include "third_party/base/span.h"
#include "v8/include/cppgc/garbage-collected.h"
#include "v8/include/cppgc/member.h"
#include "v8/include/cppgc/persistent.h"
#include "v8/include/cppgc/visitor.h"
#include "xfa/fxfa/fxfa.h"
#include "xfa/fxfa/parser/cxfa_localemgr.h"
#include "xfa/fxfa/parser/cxfa_nodeowner.h"

class CFXJSE_Engine;
class CJS_Runtime;
class CScript_DataWindow;
class CScript_EventPseudoModel;
class CScript_HostPseudoModel;
class CScript_LayoutPseudoModel;
class CScript_LogPseudoModel;
class CScript_SignaturePseudoModel;
class CXFA_FFNotify;
class CXFA_Node;
class CXFA_Object;

namespace cppgc {
class Heap;
}  // namespace cppgc

enum XFA_VERSION {
  XFA_VERSION_UNKNOWN = 0,
  XFA_VERSION_200 = 200,
  XFA_VERSION_202 = 202,
  XFA_VERSION_204 = 204,
  XFA_VERSION_205 = 205,
  XFA_VERSION_206 = 206,
  XFA_VERSION_207 = 207,
  XFA_VERSION_208 = 208,
  XFA_VERSION_300 = 300,
  XFA_VERSION_301 = 301,
  XFA_VERSION_303 = 303,
  XFA_VERSION_306 = 306,
  XFA_VERSION_DEFAULT = XFA_VERSION_303,
  XFA_VERSION_MIN = 200,
  XFA_VERSION_MAX = 400,
};

class CXFA_Document final : public cppgc::GarbageCollected<CXFA_Document> {
 public:
  class LayoutProcessorIface
      : public cppgc::GarbageCollected<LayoutProcessorIface> {
   public:
    LayoutProcessorIface();
    virtual ~LayoutProcessorIface();

    virtual void Trace(cppgc::Visitor* visitor) const;
    virtual void SetForceRelayout(bool enable) = 0;
    virtual void AddChangedContainer(CXFA_Node* pContainer) = 0;

    void SetDocument(CXFA_Document* pDocument) { m_pDocument = pDocument; }
    CXFA_Document* GetDocument() const { return m_pDocument; }

   private:
    cppgc::Member<CXFA_Document> m_pDocument;
  };

  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
  ~CXFA_Document();

  void Trace(cppgc::Visitor* visitor) const;

  bool HasScriptContext() const { return !!m_pScriptContext; }
  CFXJSE_Engine* InitScriptContext(CJS_Runtime* fxjs_runtime);

  // Only safe to call in situations where the context is known to exist,
  // and always returns non-NULL in those situations. In other words, we have
  // to call InitScriptContext() first to avoid a situation where the context
  // won't have an isolate set into it.
  CFXJSE_Engine* GetScriptContext() const;

  CXFA_FFNotify* GetNotify() const { return notify_.Get(); }
  CXFA_NodeOwner* GetNodeOwner() { return node_owner_; }
  cppgc::Heap* GetHeap() const;
  CXFA_LocaleMgr* GetLocaleMgr();
  CXFA_Object* GetXFAObject(XFA_HashCode wsNodeNameHash);
  CXFA_Node* GetNodeByID(CXFA_Node* pRoot, WideStringView wsID) const;
  CXFA_Node* GetNotBindNode(
      pdfium::span<cppgc::Member<CXFA_Object>> arrayNodes) const;

  LayoutProcessorIface* GetLayoutProcessor() const {
    return m_pLayoutProcessor;
  }
  CXFA_Node* GetRoot() const { return m_pRootNode; }
  void SetRoot(CXFA_Node* pNewRoot) { m_pRootNode = pNewRoot; }

  bool is_strict_scoping() const { return m_bStrictScoping; }
  void set_is_strict_scoping() { m_bStrictScoping = true; }

  bool is_scripting() const { return m_bScripting; }
  void set_is_scripting() { m_bScripting = true; }

  bool IsInteractive();
  XFA_VERSION GetCurVersionMode() const { return m_eCurVersionMode; }
  XFA_VERSION RecognizeXFAVersionNumber(const WideString& wsTemplateNS);
  FormType GetFormType() const;

  CXFA_Node* CreateNode(XFA_PacketType packet, XFA_Element eElement);

  void DoProtoMerge();
  void DoDataMerge();
  void DoDataRemerge(bool bDoDataMerge);
  CXFA_Node* DataMerge_CopyContainer(CXFA_Node* pTemplateNode,
                                     CXFA_Node* pFormNode,
                                     CXFA_Node* pDataScope,
                                     bool bOneInstance,
                                     bool bDataMerge,
                                     bool bUpLevel);
  void DataMerge_UpdateBindingRelations(CXFA_Node* pFormUpdateRoot);

  void ClearLayoutData();

  CXFA_Node* GetGlobalBinding(uint32_t dwNameHash);
  void RegisterGlobalBinding(uint32_t dwNameHash, CXFA_Node* pDataNode);

  size_t GetPendingNodesCount() const;
  CXFA_Node* GetPendingNodeAtIndex(size_t index) const;
  void AppendPendingNode(CXFA_Node* node);
  void ClearPendingNodes();
  void SetPendingNodesUnusedAndUnbound();

 private:
  CXFA_Document(CXFA_FFNotify* notify,
                cppgc::Heap* heap,
                LayoutProcessorIface* pLayout);

  UnownedPtr<cppgc::Heap> heap_;
  cppgc::Member<CXFA_FFNotify> const notify_;
  cppgc::Member<CXFA_NodeOwner> const node_owner_;
  cppgc::Member<CXFA_Node> m_pRootNode;
  std::unique_ptr<CFXJSE_Engine> m_pScriptContext;
  cppgc::Member<LayoutProcessorIface> m_pLayoutProcessor;
  cppgc::Member<CXFA_LocaleMgr> m_pLocaleMgr;
  cppgc::Member<CScript_DataWindow> m_pScriptDataWindow;
  cppgc::Member<CScript_EventPseudoModel> m_pScriptEvent;
  cppgc::Member<CScript_HostPseudoModel> m_pScriptHost;
  cppgc::Member<CScript_LogPseudoModel> m_pScriptLog;
  cppgc::Member<CScript_LayoutPseudoModel> m_pScriptLayout;
  cppgc::Member<CScript_SignaturePseudoModel> m_pScriptSignature;
  std::map<uint32_t, cppgc::Member<CXFA_Node>> m_rgGlobalBinding;
  std::vector<cppgc::Member<CXFA_Node>> m_pPendingPageSet;
  XFA_VERSION m_eCurVersionMode = XFA_VERSION_DEFAULT;
  Optional<bool> m_Interactive;
  bool m_bStrictScoping = false;
  bool m_bScripting = false;
};

#endif  // XFA_FXFA_PARSER_CXFA_DOCUMENT_H_
