// Copyright 2014 The PDFium Authors
// 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 "fxjs/xfa/cfxjse_resolveprocessor.h"

#include <algorithm>
#include <utility>
#include <vector>

#include "core/fxcrt/check.h"
#include "core/fxcrt/check_op.h"
#include "core/fxcrt/containers/contains.h"
#include "core/fxcrt/fx_extension.h"
#include "fxjs/xfa/cfxjse_engine.h"
#include "fxjs/xfa/cfxjse_nodehelper.h"
#include "fxjs/xfa/cfxjse_value.h"
#include "fxjs/xfa/cjx_object.h"
#include "xfa/fxfa/parser/cxfa_document.h"
#include "xfa/fxfa/parser/cxfa_localemgr.h"
#include "xfa/fxfa/parser/cxfa_node.h"
#include "xfa/fxfa/parser/cxfa_object.h"
#include "xfa/fxfa/parser/cxfa_occur.h"
#include "xfa/fxfa/parser/xfa_utils.h"

CFXJSE_ResolveProcessor::CFXJSE_ResolveProcessor(CFXJSE_Engine* pEngine,
                                                 CFXJSE_NodeHelper* pHelper)
    : m_pEngine(pEngine), m_pNodeHelper(pHelper) {}

CFXJSE_ResolveProcessor::~CFXJSE_ResolveProcessor() = default;

bool CFXJSE_ResolveProcessor::Resolve(v8::Isolate* pIsolate, NodeData& rnd) {
  if (!rnd.m_CurObject)
    return false;

  if (!rnd.m_CurObject->IsNode()) {
    if (rnd.m_dwStyles & XFA_ResolveFlag::kAttributes) {
      return ResolveForAttributeRs(rnd.m_CurObject, &rnd.m_Result,
                                   rnd.m_wsName.AsStringView());
    }
    return false;
  }
  if (rnd.m_dwStyles & XFA_ResolveFlag::kAnyChild)
    return ResolveAnyChild(pIsolate, rnd);

  if (rnd.m_wsName.GetLength()) {
    wchar_t wch = rnd.m_wsName[0];
    switch (wch) {
      case '$':
        return ResolveDollar(pIsolate, rnd);
      case '!':
        return ResolveExcalmatory(pIsolate, rnd);
      case '#':
        return ResolveNumberSign(pIsolate, rnd);
      case '*':
        return ResolveAsterisk(rnd);
      // TODO(dsinclair): We could probably remove this.
      case '.':
        return ResolveAnyChild(pIsolate, rnd);
      default:
        break;
    }
  }
  if (rnd.m_uHashName == XFA_HASHCODE_This && rnd.m_nLevel == 0) {
    rnd.m_Result.objects.emplace_back(m_pEngine->GetThisObject());
    return true;
  }
  if (rnd.m_CurObject->GetElementType() == XFA_Element::Xfa) {
    CXFA_Object* pObjNode =
        m_pEngine->GetDocument()->GetXFAObject(rnd.m_uHashName);
    if (pObjNode) {
      rnd.m_Result.objects.emplace_back(pObjNode);
    } else if (rnd.m_uHashName == XFA_HASHCODE_Xfa) {
      rnd.m_Result.objects.emplace_back(rnd.m_CurObject);
    } else if ((rnd.m_dwStyles & XFA_ResolveFlag::kAttributes) &&
               ResolveForAttributeRs(rnd.m_CurObject, &rnd.m_Result,
                                     rnd.m_wsName.AsStringView())) {
      return true;
    }
    if (!rnd.m_Result.objects.empty())
      FilterCondition(pIsolate, rnd.m_wsCondition, &rnd);

    return !rnd.m_Result.objects.empty();
  }
  if (!ResolveNormal(pIsolate, rnd) && rnd.m_uHashName == XFA_HASHCODE_Xfa)
    rnd.m_Result.objects.emplace_back(m_pEngine->GetDocument()->GetRoot());

  return !rnd.m_Result.objects.empty();
}

bool CFXJSE_ResolveProcessor::ResolveAnyChild(v8::Isolate* pIsolate,
                                              NodeData& rnd) {
  CXFA_Node* pParent = ToNode(rnd.m_CurObject);
  if (!pParent)
    return false;

  WideStringView wsName = rnd.m_wsName.AsStringView();
  WideString wsCondition = rnd.m_wsCondition;
  const bool bClassName = !wsName.IsEmpty() && wsName[0] == '#';
  CXFA_Node* const pChild =
      bClassName
          ? pParent->GetOneChildOfClass(wsName.Last(wsName.GetLength() - 1))
          : pParent->GetOneChildNamed(wsName);
  if (!pChild)
    return false;

  if (wsCondition.IsEmpty()) {
    rnd.m_Result.objects.emplace_back(pChild);
    return true;
  }

  std::vector<CXFA_Node*> nodes;
  for (const auto& pObject : rnd.m_Result.objects)
    nodes.push_back(pObject->AsNode());

  std::vector<CXFA_Node*> siblings = pChild->GetSiblings(bClassName);
  nodes.insert(nodes.end(), siblings.begin(), siblings.end());
  rnd.m_Result.objects =
      std::vector<cppgc::Member<CXFA_Object>>(nodes.begin(), nodes.end());
  FilterCondition(pIsolate, wsCondition, &rnd);
  return !rnd.m_Result.objects.empty();
}

bool CFXJSE_ResolveProcessor::ResolveDollar(v8::Isolate* pIsolate,
                                            NodeData& rnd) {
  WideString wsName = rnd.m_wsName;
  WideString wsCondition = rnd.m_wsCondition;
  size_t nNameLen = wsName.GetLength();
  if (nNameLen == 1) {
    rnd.m_Result.objects.emplace_back(rnd.m_CurObject);
    return true;
  }
  if (rnd.m_nLevel > 0)
    return false;

  CXFA_Document* pDocument = m_pEngine->GetDocument();
  XFA_HashCode dwNameHash = static_cast<XFA_HashCode>(
      FX_HashCode_GetW(wsName.AsStringView().Last(nNameLen - 1)));
  if (dwNameHash == XFA_HASHCODE_Xfa) {
    rnd.m_Result.objects.emplace_back(pDocument->GetRoot());
  } else {
    CXFA_Object* pObjNode = pDocument->GetXFAObject(dwNameHash);
    if (pObjNode)
      rnd.m_Result.objects.emplace_back(pObjNode);
  }
  if (!rnd.m_Result.objects.empty())
    FilterCondition(pIsolate, wsCondition, &rnd);
  return !rnd.m_Result.objects.empty();
}

bool CFXJSE_ResolveProcessor::ResolveExcalmatory(v8::Isolate* pIsolate,
                                                 NodeData& rnd) {
  if (rnd.m_nLevel > 0)
    return false;

  CXFA_Node* datasets =
      ToNode(m_pEngine->GetDocument()->GetXFAObject(XFA_HASHCODE_Datasets));
  if (!datasets)
    return false;

  NodeData rndFind;
  rndFind.m_CurObject = datasets;
  rndFind.m_wsName = rnd.m_wsName.Last(rnd.m_wsName.GetLength() - 1);
  rndFind.m_uHashName = static_cast<XFA_HashCode>(
      FX_HashCode_GetW(rndFind.m_wsName.AsStringView()));
  rndFind.m_nLevel = rnd.m_nLevel + 1;
  rndFind.m_dwStyles = XFA_ResolveFlag::kChildren;
  rndFind.m_wsCondition = rnd.m_wsCondition;
  Resolve(pIsolate, rndFind);

  rnd.m_Result.objects.insert(rnd.m_Result.objects.end(),
                              rndFind.m_Result.objects.begin(),
                              rndFind.m_Result.objects.end());
  return !rnd.m_Result.objects.empty();
}

bool CFXJSE_ResolveProcessor::ResolveNumberSign(v8::Isolate* pIsolate,
                                                NodeData& rnd) {
  WideString wsName = rnd.m_wsName.Last(rnd.m_wsName.GetLength() - 1);
  WideString wsCondition = rnd.m_wsCondition;
  CXFA_Node* curNode = ToNode(rnd.m_CurObject);
  if (ResolveForAttributeRs(curNode, &rnd.m_Result, wsName.AsStringView()))
    return true;

  NodeData rndFind;
  rndFind.m_nLevel = rnd.m_nLevel + 1;
  rndFind.m_dwStyles = rnd.m_dwStyles;
  rndFind.m_dwStyles |= XFA_ResolveFlag::kTagName;
  rndFind.m_dwStyles.Clear(XFA_ResolveFlag::kAttributes);
  rndFind.m_wsName = std::move(wsName);
  rndFind.m_uHashName = static_cast<XFA_HashCode>(
      FX_HashCode_GetW(rndFind.m_wsName.AsStringView()));
  rndFind.m_wsCondition = wsCondition;
  rndFind.m_CurObject = curNode;
  ResolveNormal(pIsolate, rndFind);
  if (rndFind.m_Result.objects.empty())
    return false;

  if (wsCondition.IsEmpty() &&
      pdfium::Contains(rndFind.m_Result.objects, curNode)) {
    rnd.m_Result.objects.emplace_back(curNode);
  } else {
    rnd.m_Result.objects.insert(rnd.m_Result.objects.end(),
                                rndFind.m_Result.objects.begin(),
                                rndFind.m_Result.objects.end());
  }
  return !rnd.m_Result.objects.empty();
}

bool CFXJSE_ResolveProcessor::ResolveForAttributeRs(
    CXFA_Object* curNode,
    CFXJSE_Engine::ResolveResult* rnd,
    WideStringView strAttr) {
  std::optional<XFA_SCRIPTATTRIBUTEINFO> info =
      XFA_GetScriptAttributeByName(curNode->GetElementType(), strAttr);
  if (!info.has_value())
    return false;

  rnd->type = CFXJSE_Engine::ResolveResult::Type::kAttribute;
  rnd->script_attribute = info.value();
  rnd->objects.emplace_back(curNode);
  return true;
}

bool CFXJSE_ResolveProcessor::ResolveNormal(v8::Isolate* pIsolate,
                                            NodeData& rnd) {
  if (rnd.m_nLevel > 32 || !rnd.m_CurObject->IsNode())
    return false;

  CXFA_Node* curNode = rnd.m_CurObject->AsNode();
  size_t nNum = rnd.m_Result.objects.size();
  Mask<XFA_ResolveFlag> dwStyles = rnd.m_dwStyles;
  WideString& wsName = rnd.m_wsName;
  XFA_HashCode uNameHash = rnd.m_uHashName;
  WideString& wsCondition = rnd.m_wsCondition;

  NodeData rndFind;
  rndFind.m_wsName = rnd.m_wsName;
  rndFind.m_wsCondition = rnd.m_wsCondition;
  rndFind.m_nLevel = rnd.m_nLevel + 1;
  rndFind.m_uHashName = uNameHash;

  std::vector<CXFA_Node*> children;
  std::vector<CXFA_Node*> properties;
  CXFA_Node* pVariablesNode = nullptr;
  CXFA_Node* pPageSetNode = nullptr;
  for (CXFA_Node* pChild = curNode->GetFirstChild(); pChild;
       pChild = pChild->GetNextSibling()) {
    if (pChild->GetElementType() == XFA_Element::Variables) {
      pVariablesNode = pChild;
      continue;
    }
    if (pChild->GetElementType() == XFA_Element::PageSet) {
      pPageSetNode = pChild;
      continue;
    }
    if (curNode->HasProperty(pChild->GetElementType()))
      properties.push_back(pChild);
    else
      children.push_back(pChild);
  }
  if ((dwStyles & XFA_ResolveFlag::kProperties) && pVariablesNode) {
    if (pVariablesNode->GetClassHashCode() == uNameHash) {
      rnd.m_Result.objects.emplace_back(pVariablesNode);
    } else {
      rndFind.m_CurObject = pVariablesNode;
      SetStylesForChild(dwStyles, rndFind);
      WideString wsSaveCondition = std::move(rndFind.m_wsCondition);
      ResolveNormal(pIsolate, rndFind);
      rndFind.m_wsCondition = std::move(wsSaveCondition);
      rnd.m_Result.objects.insert(rnd.m_Result.objects.end(),
                                  rndFind.m_Result.objects.begin(),
                                  rndFind.m_Result.objects.end());
      rndFind.m_Result.objects.clear();
    }
    if (rnd.m_Result.objects.size() > nNum) {
      FilterCondition(pIsolate, wsCondition, &rnd);
      return !rnd.m_Result.objects.empty();
    }
  }

  if (dwStyles & XFA_ResolveFlag::kChildren) {
    bool bSetFlag = false;
    if (pPageSetNode && (dwStyles & XFA_ResolveFlag::kProperties))
      children.push_back(pPageSetNode);

    for (CXFA_Node* child : children) {
      if (dwStyles & XFA_ResolveFlag::kTagName) {
        if (child->GetClassHashCode() == uNameHash)
          rnd.m_Result.objects.emplace_back(child);
      } else if (child->GetNameHash() == uNameHash) {
        rnd.m_Result.objects.emplace_back(child);
      }

      if (child->GetElementType() != XFA_Element::PageSet &&
          child->IsTransparent()) {
        if (!bSetFlag) {
          SetStylesForChild(dwStyles, rndFind);
          bSetFlag = true;
        }
        rndFind.m_CurObject = child;

        WideString wsSaveCondition = std::move(rndFind.m_wsCondition);
        ResolveNormal(pIsolate, rndFind);
        rndFind.m_wsCondition = std::move(wsSaveCondition);
        rnd.m_Result.objects.insert(rnd.m_Result.objects.end(),
                                    rndFind.m_Result.objects.begin(),
                                    rndFind.m_Result.objects.end());
        rndFind.m_Result.objects.clear();
      }
    }
    if (rnd.m_Result.objects.size() > nNum) {
      if (!(dwStyles & XFA_ResolveFlag::kALL)) {
        std::vector<CXFA_Node*> upArrayNodes;
        if (curNode->IsTransparent()) {
          CXFA_Node* pCurrent = ToNode(rnd.m_Result.objects.front().Get());
          if (pCurrent) {
            upArrayNodes =
                pCurrent->GetSiblings(!!(dwStyles & XFA_ResolveFlag::kTagName));
          }
        }
        if (upArrayNodes.size() > rnd.m_Result.objects.size()) {
          CXFA_Object* pSaveObject = rnd.m_Result.objects.front().Get();
          rnd.m_Result.objects = std::vector<cppgc::Member<CXFA_Object>>(
              upArrayNodes.begin(), upArrayNodes.end());
          rnd.m_Result.objects.front() = pSaveObject;
        }
      }
      FilterCondition(pIsolate, wsCondition, &rnd);
      return !rnd.m_Result.objects.empty();
    }
  }
  if (dwStyles & XFA_ResolveFlag::kAttributes) {
    if (ResolveForAttributeRs(curNode, &rnd.m_Result, wsName.AsStringView()))
      return true;
  }
  if (dwStyles & XFA_ResolveFlag::kProperties) {
    for (CXFA_Node* pChildProperty : properties) {
      if (pChildProperty->IsUnnamed()) {
        if (pChildProperty->GetClassHashCode() == uNameHash)
          rnd.m_Result.objects.emplace_back(pChildProperty);
        continue;
      }
      if (pChildProperty->GetNameHash() == uNameHash &&
          pChildProperty->GetElementType() != XFA_Element::Extras &&
          pChildProperty->GetElementType() != XFA_Element::Items) {
        rnd.m_Result.objects.emplace_back(pChildProperty);
      }
    }
    if (rnd.m_Result.objects.size() > nNum) {
      FilterCondition(pIsolate, wsCondition, &rnd);
      return !rnd.m_Result.objects.empty();
    }

    CXFA_Node* pProp = nullptr;
    if (XFA_Element::Subform == curNode->GetElementType() &&
        XFA_HASHCODE_Occur == uNameHash) {
      CXFA_Node* pInstanceManager = curNode->GetInstanceMgrOfSubform();
      if (pInstanceManager) {
        pProp = pInstanceManager->JSObject()->GetOrCreateProperty<CXFA_Occur>(
            0, XFA_Element::Occur);
      }
    } else {
      XFA_Element eType = XFA_GetElementByName(wsName.AsStringView());
      if (eType == XFA_Element::PageSet) {
        pProp = curNode->JSObject()->GetProperty<CXFA_Node>(0, eType);
      } else if (eType != XFA_Element::Unknown) {
        pProp = curNode->JSObject()->GetOrCreateProperty<CXFA_Node>(0, eType);
      }
    }
    if (pProp) {
      rnd.m_Result.objects.emplace_back(pProp);
      return !rnd.m_Result.objects.empty();
    }
  }

  CXFA_Node* const parentNode = curNode->GetParent();
  uint32_t uCurClassHash = curNode->GetClassHashCode();
  if (!parentNode) {
    if (uCurClassHash == uNameHash) {
      rnd.m_Result.objects.emplace_back(curNode);
      FilterCondition(pIsolate, wsCondition, &rnd);
      if (!rnd.m_Result.objects.empty())
        return true;
    }
    return false;
  }

  if (dwStyles & XFA_ResolveFlag::kSiblings) {
    CXFA_Node* child = parentNode->GetFirstChild();
    Mask<XFA_ResolveFlag> dwSubStyles = {XFA_ResolveFlag::kChildren,
                                         XFA_ResolveFlag::kProperties};
    if (dwStyles & XFA_ResolveFlag::kTagName)
      dwSubStyles |= XFA_ResolveFlag::kTagName;
    if (dwStyles & XFA_ResolveFlag::kALL)
      dwSubStyles |= XFA_ResolveFlag::kALL;

    rndFind.m_dwStyles = dwSubStyles;
    while (child) {
      if (child == curNode) {
        if (dwStyles & XFA_ResolveFlag::kTagName) {
          if (uCurClassHash == uNameHash)
            rnd.m_Result.objects.emplace_back(curNode);
        } else {
          if (child->GetNameHash() == uNameHash) {
            rnd.m_Result.objects.emplace_back(curNode);
            if (rnd.m_nLevel == 0 && wsCondition.IsEmpty()) {
              rnd.m_Result.objects.clear();
              rnd.m_Result.objects.emplace_back(curNode);
              return true;
            }
          }
        }
        child = child->GetNextSibling();
        continue;
      }

      if (dwStyles & XFA_ResolveFlag::kTagName) {
        if (child->GetClassHashCode() == uNameHash)
          rnd.m_Result.objects.emplace_back(child);
      } else if (child->GetNameHash() == uNameHash) {
        rnd.m_Result.objects.emplace_back(child);
      }

      bool bInnerSearch = false;
      if (parentNode->HasProperty(child->GetElementType())) {
        if ((child->GetElementType() == XFA_Element::Variables ||
             child->GetElementType() == XFA_Element::PageSet)) {
          bInnerSearch = true;
        }
      } else if (child->IsTransparent()) {
        bInnerSearch = true;
      }
      if (bInnerSearch) {
        rndFind.m_CurObject = child;
        WideString wsOriginCondition = std::move(rndFind.m_wsCondition);
        Mask<XFA_ResolveFlag> dwOriginStyle = rndFind.m_dwStyles;
        rndFind.m_dwStyles = dwOriginStyle | XFA_ResolveFlag::kALL;
        ResolveNormal(pIsolate, rndFind);
        rndFind.m_dwStyles = dwOriginStyle;
        rndFind.m_wsCondition = std::move(wsOriginCondition);
        rnd.m_Result.objects.insert(rnd.m_Result.objects.end(),
                                    rndFind.m_Result.objects.begin(),
                                    rndFind.m_Result.objects.end());
        rndFind.m_Result.objects.clear();
      }
      child = child->GetNextSibling();
    }
    if (rnd.m_Result.objects.size() > nNum) {
      if (parentNode->IsTransparent()) {
        std::vector<CXFA_Node*> upArrayNodes;
        CXFA_Node* pCurrent = ToNode(rnd.m_Result.objects.front().Get());
        if (pCurrent) {
          upArrayNodes =
              pCurrent->GetSiblings(!!(dwStyles & XFA_ResolveFlag::kTagName));
        }
        if (upArrayNodes.size() > rnd.m_Result.objects.size()) {
          CXFA_Object* pSaveObject = rnd.m_Result.objects.front().Get();
          rnd.m_Result.objects = std::vector<cppgc::Member<CXFA_Object>>(
              upArrayNodes.begin(), upArrayNodes.end());
          rnd.m_Result.objects.front() = pSaveObject;
        }
      }
      FilterCondition(pIsolate, wsCondition, &rnd);
      return !rnd.m_Result.objects.empty();
    }
  }

  if (dwStyles & XFA_ResolveFlag::kParent) {
    Mask<XFA_ResolveFlag> dwSubStyles = {XFA_ResolveFlag::kSiblings,
                                         XFA_ResolveFlag::kParent,
                                         XFA_ResolveFlag::kProperties};
    if (dwStyles & XFA_ResolveFlag::kTagName)
      dwSubStyles |= XFA_ResolveFlag::kTagName;
    if (dwStyles & XFA_ResolveFlag::kALL)
      dwSubStyles |= XFA_ResolveFlag::kALL;

    m_pEngine->AddObjectToUpArray(parentNode);
    rndFind.m_dwStyles = dwSubStyles;
    rndFind.m_CurObject = parentNode;
    ResolveNormal(pIsolate, rndFind);
    rnd.m_Result.objects.insert(rnd.m_Result.objects.end(),
                                rndFind.m_Result.objects.begin(),
                                rndFind.m_Result.objects.end());
    rndFind.m_Result.objects.clear();
    if (rnd.m_Result.objects.size() > nNum)
      return true;
  }
  return false;
}

bool CFXJSE_ResolveProcessor::ResolveAsterisk(NodeData& rnd) {
  CXFA_Node* curNode = ToNode(rnd.m_CurObject);
  std::vector<CXFA_Node*> array = curNode->GetNodeListWithFilter(
      {XFA_NodeFilter::kChildren, XFA_NodeFilter::kProperties});
  rnd.m_Result.objects.insert(rnd.m_Result.objects.end(), array.begin(),
                              array.end());
  return !rnd.m_Result.objects.empty();
}

int32_t CFXJSE_ResolveProcessor::GetFilter(WideStringView wsExpression,
                                           int32_t nStart,
                                           NodeData& rnd) {
  DCHECK(nStart > -1);

  int32_t iLength = wsExpression.GetLength();
  if (nStart >= iLength)
    return 0;

  WideString& wsName = rnd.m_wsName;
  WideString& wsCondition = rnd.m_wsCondition;
  int32_t nNameCount = 0;
  int32_t nConditionCount = 0;
  {
    // Span's lifetime must end before ReleaseBuffer() below.
    pdfium::span<wchar_t> pNameBuf = wsName.GetBuffer(iLength - nStart);
    pdfium::span<wchar_t> pConditionBuf =
        wsCondition.GetBuffer(iLength - nStart);
    pdfium::span<const wchar_t> pSrc = wsExpression.span();
    std::vector<int32_t> stack;
    int32_t nType = -1;
    wchar_t wPrev = 0;
    wchar_t wCur;
    bool bIsCondition = false;
    while (nStart < iLength) {
      wCur = pSrc[nStart++];
      if (wCur == '.') {
        if (nNameCount == 0) {
          rnd.m_dwStyles |= XFA_ResolveFlag::kAnyChild;
          continue;
        }
        if (wPrev == '\\') {
          pNameBuf[nNameCount - 1] = wPrev = '.';
          continue;
        }

        wchar_t wLookahead = nStart < iLength ? pSrc[nStart] : 0;
        if (wLookahead != '[' && wLookahead != '(' && nType < 0)
          break;
      }
      if (wCur == '[' || wCur == '(') {
        bIsCondition = true;
      } else if (wCur == '.' && nStart < iLength &&
                 (pSrc[nStart] == '[' || pSrc[nStart] == '(')) {
        bIsCondition = true;
      }
      if (bIsCondition)
        pConditionBuf[nConditionCount++] = wCur;
      else
        pNameBuf[nNameCount++] = wCur;

      if ((nType == 0 && wCur == ']') || (nType == 1 && wCur == ')') ||
          (nType == 2 && wCur == '"')) {
        nType = stack.empty() ? -1 : stack.back();
        if (!stack.empty())
          stack.pop_back();
      } else if (wCur == '[') {
        stack.push_back(nType);
        nType = 0;
      } else if (wCur == '(') {
        stack.push_back(nType);
        nType = 1;
      } else if (wCur == '"') {
        stack.push_back(nType);
        nType = 2;
      }
      wPrev = wCur;
    }
    if (!stack.empty())
      return -1;
  }
  wsName.ReleaseBuffer(nNameCount);
  wsCondition.ReleaseBuffer(nConditionCount);
  wsName.TrimWhitespace();
  wsCondition.TrimWhitespace();
  rnd.m_uHashName =
      static_cast<XFA_HashCode>(FX_HashCode_GetW(wsName.AsStringView()));
  return nStart;
}

void CFXJSE_ResolveProcessor::ConditionArray(size_t iCurIndex,
                                             WideString wsCondition,
                                             size_t iFoundCount,
                                             NodeData* pRnd) {
  size_t iLen = wsCondition.GetLength();
  bool bRelative = false;
  bool bAll = false;
  size_t i = 1;
  for (; i < iLen; ++i) {
    wchar_t ch = wsCondition[i];
    if (ch == ' ')
      continue;
    if (ch == '+' || ch == '-')
      bRelative = true;
    else if (ch == '*')
      bAll = true;

    break;
  }
  if (bAll) {
    if (pRnd->m_dwStyles & XFA_ResolveFlag::kCreateNode) {
      if (pRnd->m_dwStyles & XFA_ResolveFlag::kBind) {
        m_pNodeHelper->m_pCreateParent = ToNode(pRnd->m_CurObject);
        m_pNodeHelper->m_iCreateCount = 1;
        pRnd->m_Result.objects.clear();
        m_pNodeHelper->m_iCurAllStart = -1;
        m_pNodeHelper->m_pAllStartParent = nullptr;
      } else if (m_pNodeHelper->m_iCurAllStart == -1) {
        m_pNodeHelper->m_iCurAllStart = m_iCurStart;
        m_pNodeHelper->m_pAllStartParent = ToNode(pRnd->m_CurObject);
      }
    } else if (pRnd->m_dwStyles & XFA_ResolveFlag::kBindNew) {
      if (m_pNodeHelper->m_iCurAllStart == -1)
        m_pNodeHelper->m_iCurAllStart = m_iCurStart;
    }
    return;
  }
  if (iFoundCount == 1 && !iLen)
    return;

  int32_t iIndex = wsCondition.Substr(i, iLen - 1 - i).GetInteger();
  if (bRelative)
    iIndex += iCurIndex;

  if (iIndex < 0 || static_cast<size_t>(iIndex) >= iFoundCount) {
    if (pRnd->m_dwStyles & XFA_ResolveFlag::kCreateNode) {
      m_pNodeHelper->m_pCreateParent = ToNode(pRnd->m_CurObject);
      m_pNodeHelper->m_iCreateCount = iIndex - iFoundCount + 1;
    }
    pRnd->m_Result.objects.clear();
  } else {
    pRnd->m_Result.objects = std::vector<cppgc::Member<CXFA_Object>>(
        1, pRnd->m_Result.objects[iIndex]);
  }
}

void CFXJSE_ResolveProcessor::FilterCondition(v8::Isolate* pIsolate,
                                              WideString wsCondition,
                                              NodeData* pRnd) {
  size_t iCurIndex = 0;
  CXFA_Node* pNode = m_pEngine->LastObjectFromUpArray();
  if (pNode) {
    const bool bIsProperty = pNode->IsProperty();
    const bool bIsClassIndex =
        pNode->IsUnnamed() ||
        (bIsProperty && pNode->GetElementType() != XFA_Element::PageSet);
    iCurIndex = pNode->GetIndex(bIsProperty, bIsClassIndex);
  }

  size_t iFoundCount = pRnd->m_Result.objects.size();
  wsCondition.TrimWhitespace();

  const size_t nLen = wsCondition.GetLength();
  if (nLen == 0) {
    if (pRnd->m_dwStyles & XFA_ResolveFlag::kALL)
      return;
    if (iFoundCount == 1)
      return;

    if (iFoundCount <= iCurIndex) {
      if (pRnd->m_dwStyles & XFA_ResolveFlag::kCreateNode) {
        m_pNodeHelper->m_pCreateParent = ToNode(pRnd->m_CurObject);
        m_pNodeHelper->m_iCreateCount = iCurIndex - iFoundCount + 1;
      }
      pRnd->m_Result.objects.clear();
      return;
    }

    pRnd->m_Result.objects = std::vector<cppgc::Member<CXFA_Object>>(
        1, pRnd->m_Result.objects[iCurIndex]);
    return;
  }

  wchar_t wTypeChar = wsCondition[0];
  switch (wTypeChar) {
    case '[':
      ConditionArray(iCurIndex, wsCondition, iFoundCount, pRnd);
      return;
    case '.':
      if (nLen > 1 && (wsCondition[1] == '[' || wsCondition[1] == '('))
        DoPredicateFilter(pIsolate, wsCondition, iFoundCount, pRnd);
      return;
    case '(':
    case '"':
    default:
      return;
  }
}

void CFXJSE_ResolveProcessor::SetStylesForChild(
    Mask<XFA_ResolveFlag> dwParentStyles,
    NodeData& rnd) {
  Mask<XFA_ResolveFlag> dwSubStyles = {XFA_ResolveFlag::kChildren,
                                       XFA_ResolveFlag::kALL};
  if (dwParentStyles & XFA_ResolveFlag::kTagName)
    dwSubStyles |= XFA_ResolveFlag::kTagName;
  rnd.m_dwStyles = dwSubStyles;
}

int32_t CFXJSE_ResolveProcessor::IndexForDataBind(
    const WideString& wsNextCondition,
    int32_t iCount) {
  if (m_pNodeHelper->CreateNodeForCondition(wsNextCondition) &&
      m_pNodeHelper->m_eLastCreateType == XFA_Element::DataGroup) {
    return 0;
  }
  return iCount - 1;
}

void CFXJSE_ResolveProcessor::DoPredicateFilter(v8::Isolate* pIsolate,
                                                WideString wsCondition,
                                                size_t iFoundCount,
                                                NodeData* pRnd) {
  DCHECK_EQ(iFoundCount, pRnd->m_Result.objects.size());
  CXFA_Script::Type eLangType = CXFA_Script::Type::Unknown;
  if (wsCondition.First(2).EqualsASCII(".[") && wsCondition.Back() == L']')
    eLangType = CXFA_Script::Type::Formcalc;
  else if (wsCondition.First(2).EqualsASCII(".(") && wsCondition.Back() == L')')
    eLangType = CXFA_Script::Type::Javascript;
  else
    return;

  WideString wsExpression = wsCondition.Substr(2, wsCondition.GetLength() - 3);
  for (size_t i = iFoundCount; i > 0; --i) {
    CFXJSE_Context::ExecutionResult exec_result =
        m_pEngine->RunScript(eLangType, wsExpression.AsStringView(),
                             pRnd->m_Result.objects[i - 1].Get());
    if (!exec_result.status || !exec_result.value->ToBoolean(pIsolate)) {
      pRnd->m_Result.objects.erase(pRnd->m_Result.objects.begin() + i - 1);
    }
  }
}

CFXJSE_ResolveProcessor::NodeData::NodeData() = default;

CFXJSE_ResolveProcessor::NodeData::~NodeData() = default;
