// 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_FDE_XML_FDE_XML_IMP_H_
#define XFA_FDE_XML_FDE_XML_IMP_H_

#include "core/fxcrt/include/fx_system.h"
#include "xfa/fde/xml/fde_xml.h"
#include "xfa/fgas/crt/fgas_memory.h"
#include "xfa/fgas/crt/fgas_stream.h"

class CFDE_BlockBuffer;
class CFDE_XMLInstruction;
class CFDE_XMLElement;
class CFDE_XMLText;
class CFDE_XMLDoc;
class CFDE_XMLDOMParser;
class CFDE_XMLParser;
class CFDE_XMLSAXParser;
class CFDE_XMLSyntaxParser;

class CFDE_XMLNode : public CFX_Target {
 public:
  enum NodeItem {
    Root = 0,
    Parent,
    FirstSibling,
    PriorSibling,
    NextSibling,
    LastSibling,
    FirstNeighbor,
    PriorNeighbor,
    NextNeighbor,
    LastNeighbor,
    FirstChild,
    LastChild
  };

  CFDE_XMLNode();

  virtual void Release() { delete this; }
  virtual FDE_XMLNODETYPE GetType() const { return FDE_XMLNODE_Unknown; }
  virtual int32_t CountChildNodes() const;
  virtual CFDE_XMLNode* GetChildNode(int32_t index) const;
  virtual int32_t GetChildNodeIndex(CFDE_XMLNode* pNode) const;
  virtual CFDE_XMLNode* GetPath(const FX_WCHAR* pPath,
                                int32_t iLength = -1,
                                FX_BOOL bQualifiedName = TRUE) const;
  virtual int32_t InsertChildNode(CFDE_XMLNode* pNode, int32_t index = -1);
  virtual void RemoveChildNode(CFDE_XMLNode* pNode);
  virtual void DeleteChildren();
  virtual CFDE_XMLNode* GetNodeItem(CFDE_XMLNode::NodeItem eItem) const;
  virtual int32_t GetNodeLevel() const;
  virtual FX_BOOL InsertNodeItem(CFDE_XMLNode::NodeItem eItem,
                                 CFDE_XMLNode* pNode);
  virtual CFDE_XMLNode* RemoveNodeItem(CFDE_XMLNode::NodeItem eItem);
  virtual CFDE_XMLNode* Clone(FX_BOOL bRecursive);
  virtual void SaveXMLNode(IFX_Stream* pXMLStream);

 public:
  ~CFDE_XMLNode();
  void CloneChildren(CFDE_XMLNode* pClone);
  CFDE_XMLNode* m_pParent;
  CFDE_XMLNode* m_pChild;
  CFDE_XMLNode* m_pPrior;
  CFDE_XMLNode* m_pNext;
};
class CFDE_XMLInstruction : public CFDE_XMLNode {
 public:
  CFDE_XMLInstruction(const CFX_WideString& wsTarget);
  virtual void Release() { delete this; }
  virtual FDE_XMLNODETYPE GetType() const { return FDE_XMLNODE_Instruction; }
  virtual CFDE_XMLNode* Clone(FX_BOOL bRecursive);
  virtual void GetTargetName(CFX_WideString& wsTarget) const {
    wsTarget = m_wsTarget;
  }
  virtual int32_t CountAttributes() const;
  virtual FX_BOOL GetAttribute(int32_t index,
                               CFX_WideString& wsAttriName,
                               CFX_WideString& wsAttriValue) const;
  virtual FX_BOOL HasAttribute(const FX_WCHAR* pwsAttriName) const;
  virtual void GetString(const FX_WCHAR* pwsAttriName,
                         CFX_WideString& wsAttriValue,
                         const FX_WCHAR* pwsDefValue = nullptr) const;
  virtual void SetString(const CFX_WideString& wsAttriName,
                         const CFX_WideString& wsAttriValue);
  virtual int32_t GetInteger(const FX_WCHAR* pwsAttriName,
                             int32_t iDefValue = 0) const;
  virtual void SetInteger(const FX_WCHAR* pwsAttriName, int32_t iAttriValue);
  virtual FX_FLOAT GetFloat(const FX_WCHAR* pwsAttriName,
                            FX_FLOAT fDefValue = 0) const;
  virtual void SetFloat(const FX_WCHAR* pwsAttriName, FX_FLOAT fAttriValue);
  virtual void RemoveAttribute(const FX_WCHAR* pwsAttriName);
  virtual int32_t CountData() const;
  virtual FX_BOOL GetData(int32_t index, CFX_WideString& wsData) const;
  virtual void AppendData(const CFX_WideString& wsData);
  virtual void RemoveData(int32_t index);

 public:
  ~CFDE_XMLInstruction() {}
  CFX_WideString m_wsTarget;
  CFX_WideStringArray m_Attributes;
  CFX_WideStringArray m_TargetData;
};
class CFDE_XMLElement : public CFDE_XMLNode {
 public:
  CFDE_XMLElement(const CFX_WideString& wsTag);
  virtual void Release() { delete this; }
  virtual FDE_XMLNODETYPE GetType() const { return FDE_XMLNODE_Element; }
  virtual CFDE_XMLNode* Clone(FX_BOOL bRecursive);
  virtual void GetTagName(CFX_WideString& wsTag) const;
  virtual void GetLocalTagName(CFX_WideString& wsTag) const;
  virtual void GetNamespacePrefix(CFX_WideString& wsPrefix) const;
  virtual void GetNamespaceURI(CFX_WideString& wsNamespace) const;
  virtual int32_t CountAttributes() const;
  virtual FX_BOOL GetAttribute(int32_t index,
                               CFX_WideString& wsAttriName,
                               CFX_WideString& wsAttriValue) const;
  virtual FX_BOOL HasAttribute(const FX_WCHAR* pwsAttriName) const;
  virtual void GetString(const FX_WCHAR* pwsAttriName,
                         CFX_WideString& wsAttriValue,
                         const FX_WCHAR* pwsDefValue = nullptr) const;
  virtual void SetString(const CFX_WideString& wsAttriName,
                         const CFX_WideString& wsAttriValue);
  virtual int32_t GetInteger(const FX_WCHAR* pwsAttriName,
                             int32_t iDefValue = 0) const;
  virtual void SetInteger(const FX_WCHAR* pwsAttriName, int32_t iAttriValue);
  virtual FX_FLOAT GetFloat(const FX_WCHAR* pwsAttriName,
                            FX_FLOAT fDefValue = 0) const;
  virtual void SetFloat(const FX_WCHAR* pwsAttriName, FX_FLOAT fAttriValue);
  virtual void RemoveAttribute(const FX_WCHAR* pwsAttriName);
  virtual void GetTextData(CFX_WideString& wsText) const;
  virtual void SetTextData(const CFX_WideString& wsText);

 public:
  ~CFDE_XMLElement();
  CFX_WideString m_wsTag;
  CFX_WideStringArray m_Attributes;
};
class CFDE_XMLText : public CFDE_XMLNode {
 public:
  CFDE_XMLText(const CFX_WideString& wsText);
  virtual void Release() { delete this; }
  virtual FDE_XMLNODETYPE GetType() const { return FDE_XMLNODE_Text; }
  virtual CFDE_XMLNode* Clone(FX_BOOL bRecursive);
  virtual void GetText(CFX_WideString& wsText) const { wsText = m_wsText; }
  virtual void SetText(const CFX_WideString& wsText) { m_wsText = wsText; }

 public:
  ~CFDE_XMLText() {}
  CFX_WideString m_wsText;
};
class CFDE_XMLDeclaration : public CFDE_XMLNode {
 public:
  CFDE_XMLDeclaration() : CFDE_XMLNode() {}
};
class CFDE_XMLCharData : public CFDE_XMLDeclaration {
 public:
  CFDE_XMLCharData(const CFX_WideString& wsCData);

  virtual void Release() { delete this; }
  virtual FDE_XMLNODETYPE GetType() const { return FDE_XMLNODE_CharData; }
  virtual CFDE_XMLNode* Clone(FX_BOOL bRecursive);
  virtual void GetCharData(CFX_WideString& wsCharData) const {
    wsCharData = m_wsCharData;
  }
  virtual void SetCharData(const CFX_WideString& wsCData) {
    m_wsCharData = wsCData;
  }

 public:
  ~CFDE_XMLCharData() {}

  CFX_WideString m_wsCharData;
};
class CFDE_XMLDoc : public CFX_Target {
 public:
  CFDE_XMLDoc();
  ~CFDE_XMLDoc();
  virtual void Release() { delete this; }
  virtual FX_BOOL LoadXML(IFX_Stream* pXMLStream,
                          int32_t iXMLPlaneSize = 8192,
                          int32_t iTextDataSize = 256,
                          FDE_XMLREADERHANDLER* pHandler = nullptr);
  virtual FX_BOOL LoadXML(CFDE_XMLParser* pXMLParser);
  virtual int32_t DoLoad(IFX_Pause* pPause = nullptr);
  virtual void CloseXML();
  virtual CFDE_XMLNode* GetRoot() const { return m_pRoot; }
  virtual void SaveXML(IFX_Stream* pXMLStream = nullptr,
                       FX_BOOL bSaveBOM = TRUE);
  virtual void SaveXMLNode(IFX_Stream* pXMLStream, CFDE_XMLNode* pNode);

 protected:
  IFX_Stream* m_pStream;
  int32_t m_iStatus;
  CFDE_XMLNode* m_pRoot;
  CFDE_XMLSyntaxParser* m_pSyntaxParser;
  CFDE_XMLParser* m_pXMLParser;
  void Reset(FX_BOOL bInitRoot);
  void ReleaseParser();
};
typedef CFX_StackTemplate<CFDE_XMLNode*> CFDE_XMLDOMNodeStack;

class CFDE_XMLParser {
 public:
  virtual ~CFDE_XMLParser() {}

  virtual void Release() = 0;
  virtual int32_t DoParser(IFX_Pause* pPause) = 0;
};

class CFDE_XMLDOMParser : public CFDE_XMLParser, public CFX_Target {
 public:
  CFDE_XMLDOMParser(CFDE_XMLNode* pRoot, CFDE_XMLSyntaxParser* pParser);
  ~CFDE_XMLDOMParser();

  virtual void Release() { delete this; }
  virtual int32_t DoParser(IFX_Pause* pPause);

 private:
  CFDE_XMLSyntaxParser* m_pParser;
  CFDE_XMLNode* m_pParent;
  CFDE_XMLNode* m_pChild;
  CFDE_XMLDOMNodeStack m_NodeStack;
  CFX_WideString m_ws1;
  CFX_WideString m_ws2;
};
class CFDE_XMLTAG : public CFX_Target {
 public:
  CFDE_XMLTAG() : eType(FDE_XMLNODE_Unknown) {}
  CFDE_XMLTAG(const CFDE_XMLTAG& src)
      : wsTagName(src.wsTagName), eType(src.eType) {}
  CFX_WideString wsTagName;
  FDE_XMLNODETYPE eType;
};
typedef CFX_ObjectStackTemplate<CFDE_XMLTAG> CFDE_XMLTagStack;
class CFDE_XMLSAXParser : public CFDE_XMLParser, public CFX_Target {
 public:
  CFDE_XMLSAXParser(FDE_XMLREADERHANDLER* pHandler,
                    CFDE_XMLSyntaxParser* pParser);
  ~CFDE_XMLSAXParser();

  virtual void Release() { delete this; }
  virtual int32_t DoParser(IFX_Pause* pPause);

 private:
  void Push(const CFDE_XMLTAG& xmlTag);
  void Pop();
  FDE_XMLREADERHANDLER* m_pHandler;
  CFDE_XMLSyntaxParser* m_pParser;
  CFDE_XMLTagStack m_TagStack;
  CFDE_XMLTAG* m_pTagTop;
  CFX_WideString m_ws1;
  CFX_WideString m_ws2;
};

class CFDE_BlockBuffer : public CFX_Target {
 public:
  CFDE_BlockBuffer(int32_t iAllocStep = 1024 * 1024);
  ~CFDE_BlockBuffer();

  FX_BOOL InitBuffer(int32_t iBufferSize = 1024 * 1024);
  FX_BOOL IsInitialized() { return m_iBufferSize / m_iAllocStep >= 1; }
  void ReleaseBuffer() { delete this; }
  FX_WCHAR* GetAvailableBlock(int32_t& iIndexInBlock);
  inline int32_t GetAllocStep() const { return m_iAllocStep; }
  inline int32_t& GetDataLengthRef() { return m_iDataLength; }
  inline void Reset(FX_BOOL bReserveData = TRUE) {
    if (!bReserveData) {
      m_iStartPosition = 0;
    }
    m_iDataLength = 0;
  }
  void SetTextChar(int32_t iIndex, FX_WCHAR ch);
  int32_t DeleteTextChars(int32_t iCount, FX_BOOL bDirection = TRUE);
  void GetTextData(CFX_WideString& wsTextData,
                   int32_t iStart = 0,
                   int32_t iLength = -1) const;

 protected:
  inline void TextDataIndex2BufIndex(const int32_t iIndex,
                                     int32_t& iBlockIndex,
                                     int32_t& iInnerIndex) const;
  void ClearBuffer();
  CFX_ArrayTemplate<FX_WCHAR*> m_BlockArray;
  int32_t m_iDataLength;
  int32_t m_iBufferSize;
  int32_t m_iAllocStep;
  int32_t m_iStartPosition;
};

class CFDE_XMLSyntaxParser : public CFX_Target {
 public:
  CFDE_XMLSyntaxParser();
  ~CFDE_XMLSyntaxParser();
  void Release() { delete this; }
  void Init(IFX_Stream* pStream,
            int32_t iXMLPlaneSize,
            int32_t iTextDataSize = 256);
  FDE_XmlSyntaxResult DoSyntaxParse();
  int32_t GetStatus() const;
  int32_t GetCurrentPos() const {
    return m_iParsedChars + (m_pStart - m_pBuffer);
  }
  FX_FILESIZE GetCurrentBinaryPos() const;
  int32_t GetCurrentNodeNumber() const { return m_iCurrentNodeNum; }
  int32_t GetLastNodeNumber() const { return m_iLastNodeNum; }

  void GetTargetName(CFX_WideString& wsTarget) const {
    m_BlockBuffer.GetTextData(wsTarget, 0, m_iTextDataLength);
  }
  void GetTagName(CFX_WideString& wsTag) const {
    m_BlockBuffer.GetTextData(wsTag, 0, m_iTextDataLength);
  }
  void GetAttributeName(CFX_WideString& wsAttriName) const {
    m_BlockBuffer.GetTextData(wsAttriName, 0, m_iTextDataLength);
  }
  void GetAttributeValue(CFX_WideString& wsAttriValue) const {
    m_BlockBuffer.GetTextData(wsAttriValue, 0, m_iTextDataLength);
  }
  void GetTextData(CFX_WideString& wsText) const {
    m_BlockBuffer.GetTextData(wsText, 0, m_iTextDataLength);
  }
  void GetTargetData(CFX_WideString& wsData) const {
    m_BlockBuffer.GetTextData(wsData, 0, m_iTextDataLength);
  }

 protected:
  enum class FDE_XmlSyntaxState {
    Text,
    Node,
    Target,
    Tag,
    AttriName,
    AttriEqualSign,
    AttriQuotation,
    AttriValue,
    Entity,
    EntityDecimal,
    EntityHex,
    CloseInstruction,
    BreakElement,
    CloseElement,
    SkipDeclNode,
    DeclCharData,
    SkipComment,
    SkipCommentOrDecl,
    SkipCData,
    TargetData
  };

  IFX_Stream* m_pStream;
  int32_t m_iXMLPlaneSize;
  int32_t m_iCurrentPos;
  int32_t m_iCurrentNodeNum;
  int32_t m_iLastNodeNum;
  int32_t m_iParsedChars;
  int32_t m_iParsedBytes;
  FX_WCHAR* m_pBuffer;
  int32_t m_iBufferChars;
  FX_BOOL m_bEOS;
  FX_WCHAR* m_pStart;
  FX_WCHAR* m_pEnd;
  FDE_XMLNODE m_CurNode;
  CFDE_XMLNodeStack m_XMLNodeStack;
  CFDE_BlockBuffer m_BlockBuffer;
  int32_t m_iAllocStep;
  int32_t& m_iDataLength;
  FX_WCHAR* m_pCurrentBlock;
  int32_t m_iIndexInBlock;
  int32_t m_iTextDataLength;
  FDE_XmlSyntaxResult m_syntaxParserResult;
  FDE_XmlSyntaxState m_syntaxParserState;
  FX_WCHAR m_wQuotationMark;
  int32_t m_iEntityStart;
  CFX_DWordStack m_SkipStack;
  FX_WCHAR m_SkipChar;
  inline void ParseTextChar(FX_WCHAR ch);
};

#endif  // XFA_FDE_XML_FDE_XML_IMP_H_
