// 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 <memory>
#include <vector>

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

class CFDE_BlockBuffer;
class CFDE_XMLInstruction;
class CFDE_XMLElement;
class CFDE_XMLText;
class CFDE_XMLDoc;
class CFDE_XMLDOMParser;
class CFDE_XMLSyntaxParser;
class IFDE_XMLParser;

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

  CFDE_XMLNode();
  virtual ~CFDE_XMLNode();

  virtual void Release();
  virtual FDE_XMLNODETYPE GetType() const;
  virtual CFDE_XMLNode* Clone(bool bRecursive);

  int32_t CountChildNodes() const;
  CFDE_XMLNode* GetChildNode(int32_t index) const;
  int32_t GetChildNodeIndex(CFDE_XMLNode* pNode) const;
  int32_t InsertChildNode(CFDE_XMLNode* pNode, int32_t index = -1);
  void RemoveChildNode(CFDE_XMLNode* pNode);
  void DeleteChildren();
  void CloneChildren(CFDE_XMLNode* pClone);

  CFDE_XMLNode* GetPath(const FX_WCHAR* pPath,
                        int32_t iLength = -1,
                        bool bQualifiedName = true) const;

  int32_t GetNodeLevel() const;
  CFDE_XMLNode* GetNodeItem(CFDE_XMLNode::NodeItem eItem) const;
  bool InsertNodeItem(CFDE_XMLNode::NodeItem eItem, CFDE_XMLNode* pNode);
  CFDE_XMLNode* RemoveNodeItem(CFDE_XMLNode::NodeItem eItem);

  void SaveXMLNode(const CFX_RetainPtr<IFGAS_Stream>& pXMLStream);

  CFDE_XMLNode* m_pParent;
  CFDE_XMLNode* m_pChild;
  CFDE_XMLNode* m_pPrior;
  CFDE_XMLNode* m_pNext;
};

class CFDE_XMLInstruction : public CFDE_XMLNode {
 public:
  explicit CFDE_XMLInstruction(const CFX_WideString& wsTarget);
  ~CFDE_XMLInstruction() override;

  // CFDE_XMLNode
  void Release() override;
  FDE_XMLNODETYPE GetType() const override;
  CFDE_XMLNode* Clone(bool bRecursive) override;

  void GetTargetName(CFX_WideString& wsTarget) const { wsTarget = m_wsTarget; }
  int32_t CountAttributes() const;
  bool GetAttribute(int32_t index,
                    CFX_WideString& wsAttriName,
                    CFX_WideString& wsAttriValue) const;
  bool HasAttribute(const FX_WCHAR* pwsAttriName) const;
  void GetString(const FX_WCHAR* pwsAttriName,
                 CFX_WideString& wsAttriValue,
                 const FX_WCHAR* pwsDefValue = nullptr) const;
  void SetString(const CFX_WideString& wsAttriName,
                 const CFX_WideString& wsAttriValue);
  int32_t GetInteger(const FX_WCHAR* pwsAttriName, int32_t iDefValue = 0) const;
  void SetInteger(const FX_WCHAR* pwsAttriName, int32_t iAttriValue);
  FX_FLOAT GetFloat(const FX_WCHAR* pwsAttriName, FX_FLOAT fDefValue = 0) const;
  void SetFloat(const FX_WCHAR* pwsAttriName, FX_FLOAT fAttriValue);
  void RemoveAttribute(const FX_WCHAR* pwsAttriName);
  int32_t CountData() const;
  bool GetData(int32_t index, CFX_WideString& wsData) const;
  void AppendData(const CFX_WideString& wsData);
  void RemoveData(int32_t index);

  CFX_WideString m_wsTarget;
  std::vector<CFX_WideString> m_Attributes;
  std::vector<CFX_WideString> m_TargetData;
};

class CFDE_XMLElement : public CFDE_XMLNode {
 public:
  explicit CFDE_XMLElement(const CFX_WideString& wsTag);
  ~CFDE_XMLElement() override;

  // CFDE_XMLNode
  void Release() override;
  FDE_XMLNODETYPE GetType() const override;
  CFDE_XMLNode* Clone(bool bRecursive) override;

  void GetTagName(CFX_WideString& wsTag) const;
  void GetLocalTagName(CFX_WideString& wsTag) const;

  void GetNamespacePrefix(CFX_WideString& wsPrefix) const;
  void GetNamespaceURI(CFX_WideString& wsNamespace) const;

  int32_t CountAttributes() const;
  bool GetAttribute(int32_t index,
                    CFX_WideString& wsAttriName,
                    CFX_WideString& wsAttriValue) const;
  bool HasAttribute(const FX_WCHAR* pwsAttriName) const;
  void RemoveAttribute(const FX_WCHAR* pwsAttriName);

  void GetString(const FX_WCHAR* pwsAttriName,
                 CFX_WideString& wsAttriValue,
                 const FX_WCHAR* pwsDefValue = nullptr) const;
  void SetString(const CFX_WideString& wsAttriName,
                 const CFX_WideString& wsAttriValue);

  int32_t GetInteger(const FX_WCHAR* pwsAttriName, int32_t iDefValue = 0) const;
  void SetInteger(const FX_WCHAR* pwsAttriName, int32_t iAttriValue);

  FX_FLOAT GetFloat(const FX_WCHAR* pwsAttriName, FX_FLOAT fDefValue = 0) const;
  void SetFloat(const FX_WCHAR* pwsAttriName, FX_FLOAT fAttriValue);

  void GetTextData(CFX_WideString& wsText) const;
  void SetTextData(const CFX_WideString& wsText);

  CFX_WideString m_wsTag;
  std::vector<CFX_WideString> m_Attributes;
};

class CFDE_XMLText : public CFDE_XMLNode {
 public:
  explicit CFDE_XMLText(const CFX_WideString& wsText);
  ~CFDE_XMLText() override;

  // CFDE_XMLNode
  void Release() override;
  FDE_XMLNODETYPE GetType() const override;
  CFDE_XMLNode* Clone(bool bRecursive) override;

  void GetText(CFX_WideString& wsText) const { wsText = m_wsText; }
  void SetText(const CFX_WideString& wsText) { m_wsText = wsText; }

  CFX_WideString m_wsText;
};

class CFDE_XMLDeclaration : public CFDE_XMLNode {
 public:
  CFDE_XMLDeclaration() {}
  ~CFDE_XMLDeclaration() override {}
};

class CFDE_XMLCharData : public CFDE_XMLDeclaration {
 public:
  explicit CFDE_XMLCharData(const CFX_WideString& wsCData);
  ~CFDE_XMLCharData() override;

  void Release() override;
  FDE_XMLNODETYPE GetType() const override;
  CFDE_XMLNode* Clone(bool bRecursive) override;

  void GetCharData(CFX_WideString& wsCharData) const {
    wsCharData = m_wsCharData;
  }
  void SetCharData(const CFX_WideString& wsCData) { m_wsCharData = wsCData; }

  CFX_WideString m_wsCharData;
};

class CFDE_XMLDoc {
 public:
  CFDE_XMLDoc();
  ~CFDE_XMLDoc();

  bool LoadXML(std::unique_ptr<IFDE_XMLParser> pXMLParser);
  int32_t DoLoad(IFX_Pause* pPause = nullptr);
  void CloseXML();
  CFDE_XMLNode* GetRoot() const { return m_pRoot; }
  void SaveXML(CFX_RetainPtr<IFGAS_Stream>& pXMLStream, bool bSaveBOM = true);
  void SaveXMLNode(const CFX_RetainPtr<IFGAS_Stream>& pXMLStream,
                   CFDE_XMLNode* pNode);

 protected:
  void Reset(bool bInitRoot);
  void ReleaseParser();

  CFX_RetainPtr<IFGAS_Stream> m_pStream;
  int32_t m_iStatus;
  CFDE_XMLNode* m_pRoot;
  CFDE_XMLSyntaxParser* m_pSyntaxParser;
  std::unique_ptr<IFDE_XMLParser> m_pXMLParser;
};

class IFDE_XMLParser {
 public:
  virtual ~IFDE_XMLParser() {}
  virtual int32_t DoParser(IFX_Pause* pPause) = 0;
};

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

  bool InitBuffer(int32_t iBufferSize = 1024 * 1024);
  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(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, 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:
  CFDE_XMLSyntaxParser();
  ~CFDE_XMLSyntaxParser();

  void Release() { delete this; }
  void Init(const CFX_RetainPtr<IFGAS_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
  };

  void ParseTextChar(FX_WCHAR ch);

  CFX_RetainPtr<IFGAS_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;
  bool m_bEOS;
  FX_WCHAR* m_pStart;
  FX_WCHAR* m_pEnd;
  FDE_XMLNODE m_CurNode;
  CFX_StackTemplate<FDE_XMLNODE> 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_StackTemplate<uint32_t> m_SkipStack;
  FX_WCHAR m_SkipChar;
};

#endif  // XFA_FDE_XML_FDE_XML_IMP_H_
