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

#include "core/fxcrt/fx_basic.h"
#include "core/fxcrt/fx_system.h"
#include "xfa/fde/xml/fde_xml.h"
#include "xfa/fgas/crt/ifgas_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_XMLSyntaxParser;

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 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 wchar_t* 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
  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 wchar_t* pwsAttriName) const;
  void GetString(const wchar_t* pwsAttriName,
                 CFX_WideString& wsAttriValue,
                 const wchar_t* pwsDefValue = nullptr) const;
  void SetString(const CFX_WideString& wsAttriName,
                 const CFX_WideString& wsAttriValue);
  int32_t GetInteger(const wchar_t* pwsAttriName, int32_t iDefValue = 0) const;
  void SetInteger(const wchar_t* pwsAttriName, int32_t iAttriValue);
  float GetFloat(const wchar_t* pwsAttriName, float fDefValue = 0) const;
  void SetFloat(const wchar_t* pwsAttriName, float fAttriValue);
  void RemoveAttribute(const wchar_t* 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
  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 wchar_t* pwsAttriName) const;
  void RemoveAttribute(const wchar_t* pwsAttriName);

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

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

  float GetFloat(const wchar_t* pwsAttriName, float fDefValue = 0) const;
  void SetFloat(const wchar_t* pwsAttriName, 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
  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;

  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<CFDE_XMLParser> pXMLParser);
  int32_t DoLoad(IFX_Pause* pPause = nullptr);
  void CloseXML();
  CFDE_XMLNode* GetRoot() const { return m_pRoot.get(); }
  void SaveXMLNode(const CFX_RetainPtr<IFGAS_Stream>& pXMLStream,
                   CFDE_XMLNode* pNode);

 private:
  int32_t m_iStatus;
  std::unique_ptr<CFDE_XMLNode> m_pRoot;
  std::unique_ptr<CFDE_XMLParser> m_pXMLParser;
  CFX_RetainPtr<IFGAS_Stream> m_pStream;
};

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; }
  wchar_t* 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, wchar_t 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();

  std::vector<std::unique_ptr<wchar_t, FxFreeDeleter>> 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 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(wchar_t 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;
  wchar_t* m_pBuffer;
  int32_t m_iBufferChars;
  bool m_bEOS;
  wchar_t* m_pStart;
  wchar_t* m_pEnd;
  FDE_XMLNODE m_CurNode;
  std::stack<FDE_XMLNODE> m_XMLNodeStack;
  CFDE_BlockBuffer m_BlockBuffer;
  int32_t m_iAllocStep;
  int32_t& m_iDataLength;
  wchar_t* m_pCurrentBlock;
  int32_t m_iIndexInBlock;
  int32_t m_iTextDataLength;
  FDE_XmlSyntaxResult m_syntaxParserResult;
  FDE_XmlSyntaxState m_syntaxParserState;
  wchar_t m_wQuotationMark;
  int32_t m_iEntityStart;
  std::stack<wchar_t> m_SkipStack;
  wchar_t m_SkipChar;
};

#endif  // XFA_FDE_XML_FDE_XML_IMP_H_
