// 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

#include "xfa/fxfa/parser/xfa_script_nodehelper.h"

#include "core/fxcrt/include/fx_ext.h"
#include "xfa/fxfa/parser/xfa_doclayout.h"
#include "xfa/fxfa/parser/xfa_document.h"
#include "xfa/fxfa/parser/xfa_localemgr.h"
#include "xfa/fxfa/parser/xfa_object.h"
#include "xfa/fxfa/parser/xfa_parser.h"
#include "xfa/fxfa/parser/xfa_script.h"
#include "xfa/fxfa/parser/xfa_script_imp.h"
#include "xfa/fxfa/parser/xfa_utils.h"

CXFA_NodeHelper::CXFA_NodeHelper(void)
    : m_eLastCreateType(XFA_ELEMENT_DataValue),
      m_pCreateParent(NULL),
      m_iCreateCount(0),
      m_iCreateFlag(XFA_RESOLVENODE_RSTYPE_CreateNodeOne),
      m_iCurAllStart(-1),
      m_pAllStartParent(NULL) {}
CXFA_NodeHelper::~CXFA_NodeHelper(void) {}
CXFA_Node* CXFA_NodeHelper::XFA_ResolveNodes_GetOneChild(
    CXFA_Node* parent,
    const FX_WCHAR* pwsName,
    FX_BOOL bIsClassName) {
  if (parent == NULL) {
    return NULL;
  }
  CXFA_NodeArray siblings;
  uint32_t uNameHash = FX_HashCode_GetW(CFX_WideStringC(pwsName), false);
  XFA_NodeAcc_TraverseAnySiblings(parent, uNameHash, &siblings, bIsClassName);
  if (siblings.GetSize() == 0) {
    return NULL;
  }
  return siblings[0];
}
int32_t CXFA_NodeHelper::XFA_CountSiblings(CXFA_Node* pNode,
                                           XFA_LOGIC_TYPE eLogicType,
                                           CXFA_NodeArray* pSiblings,
                                           FX_BOOL bIsClassName) {
  if (!pNode)
    return 0;
  CXFA_Node* parent =
      XFA_ResolveNodes_GetParent(pNode, XFA_LOGIC_NoTransparent);
  if (!parent)
    return 0;
  const XFA_PROPERTY* pProperty = XFA_GetPropertyOfElement(
      parent->GetClassID(), pNode->GetClassID(), XFA_XDPPACKET_UNKNOWN);
  if (!pProperty && eLogicType == XFA_LOGIC_Transparent) {
    parent = XFA_ResolveNodes_GetParent(pNode, XFA_LOGIC_Transparent);
    if (parent == NULL) {
      return 0;
    }
  }
  if (bIsClassName) {
    return XFA_NodeAcc_TraverseSiblings(parent, pNode->GetClassHashCode(),
                                        pSiblings, eLogicType, bIsClassName);
  } else {
    return XFA_NodeAcc_TraverseSiblings(parent, pNode->GetNameHash(), pSiblings,
                                        eLogicType, bIsClassName);
  }
}
int32_t CXFA_NodeHelper::XFA_NodeAcc_TraverseAnySiblings(
    CXFA_Node* parent,
    uint32_t dNameHash,
    CXFA_NodeArray* pSiblings,
    FX_BOOL bIsClassName) {
  if (parent == NULL || pSiblings == NULL) {
    return 0;
  }
  int32_t nCount = 0;
  int32_t i = 0;
  CXFA_NodeArray properties;
  parent->GetNodeList(properties, XFA_NODEFILTER_Properties);
  int32_t nProperties = properties.GetSize();
  for (i = 0; i < nProperties; ++i) {
    CXFA_Node* child = properties[i];
    if (bIsClassName) {
      if (child->GetClassHashCode() == dNameHash) {
        pSiblings->Add(child);
        nCount++;
      }
    } else {
      if (child->GetNameHash() == dNameHash) {
        pSiblings->Add(child);
        nCount++;
      }
    }
    if (nCount > 0) {
      return nCount;
    }
    nCount += XFA_NodeAcc_TraverseAnySiblings(child, dNameHash, pSiblings,
                                              bIsClassName);
  }
  CXFA_NodeArray children;
  parent->GetNodeList(children, XFA_NODEFILTER_Children);
  int32_t nChildren = children.GetSize();
  for (i = 0; i < nChildren; i++) {
    CXFA_Node* child = children[i];
    if (bIsClassName) {
      if (child->GetClassHashCode() == dNameHash) {
        if (pSiblings) {
          pSiblings->Add(child);
        }
        nCount++;
      }
    } else {
      if (child->GetNameHash() == dNameHash) {
        if (pSiblings) {
          pSiblings->Add(child);
        }
        nCount++;
      }
    }
    if (nCount > 0) {
      return nCount;
    }
    nCount += XFA_NodeAcc_TraverseAnySiblings(child, dNameHash, pSiblings,
                                              bIsClassName);
  }
  return nCount;
}
int32_t CXFA_NodeHelper::XFA_NodeAcc_TraverseSiblings(CXFA_Node* parent,
                                                      uint32_t dNameHash,
                                                      CXFA_NodeArray* pSiblings,
                                                      XFA_LOGIC_TYPE eLogicType,
                                                      FX_BOOL bIsClassName,
                                                      FX_BOOL bIsFindProperty) {
  if (parent == NULL || pSiblings == NULL) {
    return 0;
  }
  int32_t nCount = 0;
  int32_t i = 0;
  if (bIsFindProperty) {
    CXFA_NodeArray properties;
    parent->GetNodeList(properties, XFA_NODEFILTER_Properties);
    int32_t nProperties = properties.GetSize();
    for (i = 0; i < nProperties; ++i) {
      CXFA_Node* child = properties[i];
      if (bIsClassName) {
        if (child->GetClassHashCode() == dNameHash) {
          pSiblings->Add(child);
          nCount++;
        }
      } else {
        if (child->GetNameHash() == dNameHash) {
          if (child->GetClassID() != XFA_ELEMENT_PageSet &&
              child->GetClassID() != XFA_ELEMENT_Extras &&
              child->GetClassID() != XFA_ELEMENT_Items) {
            pSiblings->Add(child);
            nCount++;
          }
        }
      }
      if (child->IsUnnamed() && child->GetClassID() == XFA_ELEMENT_PageSet) {
        nCount += XFA_NodeAcc_TraverseSiblings(child, dNameHash, pSiblings,
                                               eLogicType, bIsClassName, FALSE);
      }
    }
    if (nCount > 0) {
      return nCount;
    }
  }
  CXFA_NodeArray children;
  parent->GetNodeList(children, XFA_NODEFILTER_Children);
  int32_t nChildren = children.GetSize();
  for (i = 0; i < nChildren; i++) {
    CXFA_Node* child = children[i];
    if (child->GetClassID() == XFA_ELEMENT_Variables) {
      continue;
    }
    if (bIsClassName) {
      if (child->GetClassHashCode() == dNameHash) {
        if (pSiblings) {
          pSiblings->Add(child);
        }
        nCount++;
      }
    } else {
      if (child->GetNameHash() == dNameHash) {
        if (pSiblings) {
          pSiblings->Add(child);
        }
        nCount++;
      }
    }
    if (eLogicType == XFA_LOGIC_NoTransparent) {
      continue;
    }
    if (XFA_NodeIsTransparent(child) &&
        child->GetClassID() != XFA_ELEMENT_PageSet) {
      nCount += XFA_NodeAcc_TraverseSiblings(child, dNameHash, pSiblings,
                                             eLogicType, bIsClassName, FALSE);
    }
  }
  return nCount;
}
CXFA_Node* CXFA_NodeHelper::XFA_ResolveNodes_GetParent(
    CXFA_Node* pNode,
    XFA_LOGIC_TYPE eLogicType) {
  if (!pNode) {
    return NULL;
  }
  if (eLogicType == XFA_LOGIC_NoTransparent) {
    return pNode->GetNodeItem(XFA_NODEITEM_Parent);
  }
  CXFA_Node* parent;
  CXFA_Node* node = pNode;
  while (TRUE) {
    parent = XFA_ResolveNodes_GetParent(node);
    if (parent == NULL) {
      break;
    }
    XFA_ELEMENT parentElement = parent->GetClassID();
    if ((!parent->IsUnnamed() && parentElement != XFA_ELEMENT_SubformSet) ||
        parentElement == XFA_ELEMENT_Variables) {
      break;
    }
    node = parent;
  }
  return parent;
}
int32_t CXFA_NodeHelper::XFA_GetIndex(CXFA_Node* pNode,
                                      XFA_LOGIC_TYPE eLogicType,
                                      FX_BOOL bIsProperty,
                                      FX_BOOL bIsClassIndex) {
  CXFA_Node* parent =
      XFA_ResolveNodes_GetParent(pNode, XFA_LOGIC_NoTransparent);
  if (parent == NULL) {
    return 0;
  }
  if (!bIsProperty && eLogicType == XFA_LOGIC_Transparent) {
    parent = XFA_ResolveNodes_GetParent(pNode, XFA_LOGIC_Transparent);
    if (parent == NULL) {
      return 0;
    }
  }
  uint32_t dwHashName = pNode->GetNameHash();
  if (bIsClassIndex) {
    dwHashName = pNode->GetClassHashCode();
  }
  CXFA_NodeArray siblings;
  int32_t iSize = XFA_NodeAcc_TraverseSiblings(parent, dwHashName, &siblings,
                                               eLogicType, bIsClassIndex);
  for (int32_t i = 0; i < iSize; ++i) {
    CXFA_Node* child = siblings[i];
    if (child == pNode) {
      return i;
    }
  }
  return 0;
}
void CXFA_NodeHelper::XFA_GetNameExpression(CXFA_Node* refNode,
                                            CFX_WideString& wsName,
                                            FX_BOOL bIsAllPath,
                                            XFA_LOGIC_TYPE eLogicType) {
  wsName.clear();
  if (bIsAllPath) {
    XFA_GetNameExpression(refNode, wsName, FALSE, eLogicType);
    CFX_WideString wsParent;
    CXFA_Node* parent =
        XFA_ResolveNodes_GetParent(refNode, XFA_LOGIC_NoTransparent);
    while (parent) {
      XFA_GetNameExpression(parent, wsParent, FALSE, eLogicType);
      wsParent += L".";
      wsParent += wsName;
      wsName = wsParent;
      parent = XFA_ResolveNodes_GetParent(parent, XFA_LOGIC_NoTransparent);
    }
    return;
  }

  CFX_WideStringC wsTagName;
  CFX_WideString ws;
  FX_BOOL bIsProperty = XFA_NodeIsProperty(refNode);
  if (refNode->IsUnnamed() ||
      (bIsProperty && refNode->GetClassID() != XFA_ELEMENT_PageSet)) {
    refNode->GetClassName(wsTagName);
    ws = wsTagName;
    wsName.Format(L"#%s[%d]", ws.c_str(),
                  XFA_GetIndex(refNode, eLogicType, bIsProperty, TRUE));
    return;
  }
  ws = refNode->GetCData(XFA_ATTRIBUTE_Name);
  ws.Replace(L".", L"\\.");
  wsName.Format(L"%s[%d]", ws.c_str(),
                XFA_GetIndex(refNode, eLogicType, bIsProperty, FALSE));
}

FX_BOOL CXFA_NodeHelper::XFA_NodeIsTransparent(CXFA_Node* refNode) {
  if (refNode == NULL) {
    return FALSE;
  }
  XFA_ELEMENT eRefNode = refNode->GetClassID();
  if ((refNode->IsUnnamed() && refNode->IsContainerNode()) ||
      eRefNode == XFA_ELEMENT_SubformSet || eRefNode == XFA_ELEMENT_Area ||
      eRefNode == XFA_ELEMENT_Proto) {
    return TRUE;
  }
  return FALSE;
}
FX_BOOL CXFA_NodeHelper::XFA_CreateNode_ForCondition(
    CFX_WideString& wsCondition) {
  int32_t iLen = wsCondition.GetLength();
  CFX_WideString wsIndex(L"0");
  FX_BOOL bAll = FALSE;
  if (iLen == 0) {
    m_iCreateFlag = XFA_RESOLVENODE_RSTYPE_CreateNodeOne;
    return FALSE;
  }
  if (wsCondition.GetAt(0) == '[') {
    int32_t i = 1;
    for (; i < iLen; ++i) {
      FX_WCHAR ch = wsCondition[i];
      if (ch == ' ') {
        continue;
      }
      if (ch == '+' || ch == '-') {
        break;
      } else if (ch == '*') {
        bAll = TRUE;
        break;
      } else {
        break;
      }
    }
    if (bAll) {
      wsIndex = FX_WSTRC(L"1");
      m_iCreateFlag = XFA_RESOLVENODE_RSTYPE_CreateNodeAll;
    } else {
      m_iCreateFlag = XFA_RESOLVENODE_RSTYPE_CreateNodeOne;
      wsIndex = wsCondition.Mid(i, iLen - 1 - i);
    }
    int32_t iIndex = wsIndex.GetInteger();
    m_iCreateCount = iIndex;
    return TRUE;
  }
  return FALSE;
}
FX_BOOL CXFA_NodeHelper::XFA_ResolveNodes_CreateNode(
    CFX_WideString wsName,
    CFX_WideString wsCondition,
    FX_BOOL bLastNode,
    CXFA_ScriptContext* pScriptContext) {
  if (m_pCreateParent == NULL) {
    return FALSE;
  }
  FX_BOOL bIsClassName = FALSE;
  FX_BOOL bResult = FALSE;
  if (wsName.GetAt(0) == '!') {
    wsName = wsName.Right(wsName.GetLength() - 1);
    m_pCreateParent = ToNode(
        pScriptContext->GetDocument()->GetXFAObject(XFA_HASHCODE_Datasets));
  }
  if (wsName.GetAt(0) == '#') {
    bIsClassName = TRUE;
    wsName = wsName.Right(wsName.GetLength() - 1);
  }
  if (m_iCreateCount == 0) {
    XFA_CreateNode_ForCondition(wsCondition);
  }
  if (bIsClassName) {
    const XFA_ELEMENTINFO* lpElement = XFA_GetElementByName(wsName.AsStringC());
    if (lpElement == NULL) {
      return FALSE;
    }
    for (int32_t iIndex = 0; iIndex < m_iCreateCount; iIndex++) {
      CXFA_Node* pNewNode =
          m_pCreateParent->CreateSamePacketNode(lpElement->eName);
      if (pNewNode) {
        m_pCreateParent->InsertChild(pNewNode);
        if (iIndex == m_iCreateCount - 1) {
          m_pCreateParent = pNewNode;
        }
        bResult = TRUE;
      }
    }
  } else {
    XFA_ELEMENT eClassType = XFA_ELEMENT_DataGroup;
    if (bLastNode) {
      eClassType = m_eLastCreateType;
    }
    for (int32_t iIndex = 0; iIndex < m_iCreateCount; iIndex++) {
      CXFA_Node* pNewNode = m_pCreateParent->CreateSamePacketNode(eClassType);
      if (pNewNode) {
        pNewNode->SetAttribute(XFA_ATTRIBUTE_Name, wsName.AsStringC());
        pNewNode->CreateXMLMappingNode();
        m_pCreateParent->InsertChild(pNewNode);
        if (iIndex == m_iCreateCount - 1) {
          m_pCreateParent = pNewNode;
        }
        bResult = TRUE;
      }
    }
  }
  if (!bResult) {
    m_pCreateParent = NULL;
  }
  return bResult;
}
void CXFA_NodeHelper::XFA_SetCreateNodeType(CXFA_Node* refNode) {
  if (refNode == NULL) {
    return;
  }
  if (refNode->GetClassID() == XFA_ELEMENT_Subform) {
    m_eLastCreateType = XFA_ELEMENT_DataGroup;
  } else if (refNode->GetClassID() == XFA_ELEMENT_Field) {
    m_eLastCreateType = XFA_FieldIsMultiListBox(refNode)
                            ? XFA_ELEMENT_DataGroup
                            : XFA_ELEMENT_DataValue;
  } else if (refNode->GetClassID() == XFA_ELEMENT_ExclGroup) {
    m_eLastCreateType = XFA_ELEMENT_DataValue;
  }
}
FX_BOOL CXFA_NodeHelper::XFA_NodeIsProperty(CXFA_Node* refNode) {
  CXFA_Node* parent =
      XFA_ResolveNodes_GetParent(refNode, XFA_LOGIC_NoTransparent);
  return parent && refNode &&
         XFA_GetPropertyOfElement(parent->GetClassID(), refNode->GetClassID(),
                                  XFA_XDPPACKET_UNKNOWN);
}
