// Copyright 2017 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 "fxjs/xfa/cjx_node.h"

#include <memory>
#include <utility>
#include <vector>

#include "core/fxcrt/cfx_memorystream.h"
#include "core/fxcrt/cfx_readonlymemorystream.h"
#include "core/fxcrt/fx_codepage.h"
#include "core/fxcrt/xml/cfx_xmldocument.h"
#include "core/fxcrt/xml/cfx_xmlelement.h"
#include "core/fxcrt/xml/cfx_xmlparser.h"
#include "fxjs/fxv8.h"
#include "fxjs/js_resources.h"
#include "fxjs/xfa/cfxjse_engine.h"
#include "xfa/fxfa/cxfa_eventparam.h"
#include "xfa/fxfa/cxfa_ffdoc.h"
#include "xfa/fxfa/cxfa_ffnotify.h"
#include "xfa/fxfa/parser/cxfa_document.h"
#include "xfa/fxfa/parser/cxfa_document_builder.h"
#include "xfa/fxfa/parser/cxfa_node.h"
#include "xfa/fxfa/parser/xfa_basic_data.h"
#include "xfa/fxfa/parser/xfa_utils.h"

namespace {

enum class EventAppliesTo : uint8_t {
  kNone = 0,
  kAll = 1,
  kAllNonRecursive = 2,
  kSubform = 3,
  kFieldOrExclusion = 4,
  kField = 5,
  kSignature = 6,
  kChoiceList = 7
};

struct ExecEventParaInfo {
 public:
  uint32_t m_uHash;  // hashed as wide string.
  XFA_EVENTTYPE m_eventType;
  EventAppliesTo m_validFlags;
};

#undef PARA
#define PARA(a, b, c, d) a, c, EventAppliesTo::d
const ExecEventParaInfo kExecEventParaInfoTable[] = {
    {PARA(0x109d7ce7, "mouseEnter", XFA_EVENT_MouseEnter, kField)},
    {PARA(0x1bfc72d9, "preOpen", XFA_EVENT_PreOpen, kChoiceList)},
    {PARA(0x2196a452, "initialize", XFA_EVENT_Initialize, kAll)},
    {PARA(0x27410f03, "mouseExit", XFA_EVENT_MouseExit, kField)},
    {PARA(0x36f1c6d8, "preSign", XFA_EVENT_PreSign, kSignature)},
    {PARA(0x4731d6ba, "exit", XFA_EVENT_Exit, kAllNonRecursive)},
    {PARA(0x7233018a, "validate", XFA_EVENT_Validate, kAll)},
    {PARA(0x8808385e, "indexChange", XFA_EVENT_IndexChange, kSubform)},
    {PARA(0x891f4606, "change", XFA_EVENT_Change, kFieldOrExclusion)},
    {PARA(0x9f693b21, "mouseDown", XFA_EVENT_MouseDown, kField)},
    {PARA(0xcdce56b3, "full", XFA_EVENT_Full, kFieldOrExclusion)},
    {PARA(0xd576d08e, "mouseUp", XFA_EVENT_MouseUp, kField)},
    {PARA(0xd95657a6, "click", XFA_EVENT_Click, kFieldOrExclusion)},
    {PARA(0xdbfbe02e, "calculate", XFA_EVENT_Calculate, kAll)},
    {PARA(0xe25fa7b8, "postOpen", XFA_EVENT_PostOpen, kChoiceList)},
    {PARA(0xe28dce7e, "enter", XFA_EVENT_Enter, kAllNonRecursive)},
    {PARA(0xfd54fbb7, "postSign", XFA_EVENT_PostSign, kSignature)},
};
#undef PARA

const ExecEventParaInfo* GetExecEventParaInfoByName(
    WideStringView wsEventName) {
  if (wsEventName.IsEmpty())
    return nullptr;

  uint32_t uHash = FX_HashCode_GetW(wsEventName);
  auto* result = std::lower_bound(
      std::begin(kExecEventParaInfoTable), std::end(kExecEventParaInfoTable),
      uHash, [](const ExecEventParaInfo& iter, const uint16_t& hash) {
        return iter.m_uHash < hash;
      });
  if (result != std::end(kExecEventParaInfoTable) && result->m_uHash == uHash)
    return result;
  return nullptr;
}

}  // namespace

const CJX_MethodSpec CJX_Node::MethodSpecs[] = {
    {"applyXSL", applyXSL_static},
    {"assignNode", assignNode_static},
    {"clone", clone_static},
    {"getAttribute", getAttribute_static},
    {"getElement", getElement_static},
    {"isPropertySpecified", isPropertySpecified_static},
    {"loadXML", loadXML_static},
    {"saveFilteredXML", saveFilteredXML_static},
    {"saveXML", saveXML_static},
    {"setAttribute", setAttribute_static},
    {"setElement", setElement_static}};

CJX_Node::CJX_Node(CXFA_Node* node) : CJX_Tree(node) {
  DefineMethods(MethodSpecs);
}

CJX_Node::~CJX_Node() = default;

bool CJX_Node::DynamicTypeIs(TypeTag eType) const {
  return eType == static_type__ || ParentType__::DynamicTypeIs(eType);
}

CJS_Result CJX_Node::applyXSL(CFX_V8* runtime,
                              const std::vector<v8::Local<v8::Value>>& params) {
  if (params.size() != 1)
    return CJS_Result::Failure(JSMessage::kParamError);

  // TODO(weili): check whether we need to implement this, pdfium:501.
  return CJS_Result::Success();
}

CJS_Result CJX_Node::assignNode(
    CFX_V8* runtime,
    const std::vector<v8::Local<v8::Value>>& params) {
  if (params.empty() || params.size() > 3)
    return CJS_Result::Failure(JSMessage::kParamError);

  // TODO(weili): check whether we need to implement this, pdfium:501.
  return CJS_Result::Success();
}

CJS_Result CJX_Node::clone(CFX_V8* runtime,
                           const std::vector<v8::Local<v8::Value>>& params) {
  if (params.size() != 1)
    return CJS_Result::Failure(JSMessage::kParamError);

  CXFA_Node* pCloneNode = GetXFANode()->Clone(runtime->ToBoolean(params[0]));
  return CJS_Result::Success(
      GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap(
          pCloneNode));
}

CJS_Result CJX_Node::getAttribute(
    CFX_V8* runtime,
    const std::vector<v8::Local<v8::Value>>& params) {
  if (params.size() != 1)
    return CJS_Result::Failure(JSMessage::kParamError);

  WideString expression = runtime->ToWideString(params[0]);
  return CJS_Result::Success(runtime->NewString(
      GetAttributeByString(expression.AsStringView()).ToUTF8().AsStringView()));
}

CJS_Result CJX_Node::getElement(
    CFX_V8* runtime,
    const std::vector<v8::Local<v8::Value>>& params) {
  if (params.empty() || params.size() > 2)
    return CJS_Result::Failure(JSMessage::kParamError);

  WideString expression = runtime->ToWideString(params[0]);
  int32_t iValue = params.size() >= 2 ? runtime->ToInt32(params[1]) : 0;
  XFA_Element eElement = XFA_GetElementByName(expression.AsStringView());
  if (eElement == XFA_Element::Unknown)
    return CJS_Result::Success(runtime->NewNull());

  CXFA_Node* pNode = GetOrCreateProperty<CXFA_Node>(iValue, eElement);
  if (!pNode)
    return CJS_Result::Success(runtime->NewNull());

  return CJS_Result::Success(
      GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap(pNode));
}

CJS_Result CJX_Node::isPropertySpecified(
    CFX_V8* runtime,
    const std::vector<v8::Local<v8::Value>>& params) {
  if (params.empty() || params.size() > 3)
    return CJS_Result::Failure(JSMessage::kParamError);

  WideString expression = runtime->ToWideString(params[0]);
  Optional<XFA_ATTRIBUTEINFO> attr =
      XFA_GetAttributeByName(expression.AsStringView());
  if (attr.has_value() && HasAttribute(attr.value().attribute))
    return CJS_Result::Success(runtime->NewBoolean(true));

  XFA_Element eType = XFA_GetElementByName(expression.AsStringView());
  if (eType == XFA_Element::Unknown)
    return CJS_Result::Success(runtime->NewBoolean(false));

  bool bParent = params.size() < 2 || runtime->ToBoolean(params[1]);
  int32_t iIndex = params.size() == 3 ? runtime->ToInt32(params[2]) : 0;
  bool bHas = !!GetOrCreateProperty<CXFA_Node>(iIndex, eType);
  if (!bHas && bParent && GetXFANode()->GetParent()) {
    // Also check on the parent.
    auto* jsnode = GetXFANode()->GetParent()->JSObject();
    bHas = jsnode->HasAttribute(attr.value().attribute) ||
           !!jsnode->GetOrCreateProperty<CXFA_Node>(iIndex, eType);
  }
  return CJS_Result::Success(runtime->NewBoolean(bHas));
}

CJS_Result CJX_Node::loadXML(CFX_V8* runtime,
                             const std::vector<v8::Local<v8::Value>>& params) {
  if (params.empty() || params.size() > 3)
    return CJS_Result::Failure(JSMessage::kParamError);

  ByteString expression = runtime->ToByteString(params[0]);
  if (expression.IsEmpty())
    return CJS_Result::Success();

  bool bIgnoreRoot = true;
  if (params.size() >= 2)
    bIgnoreRoot = runtime->ToBoolean(params[1]);

  bool bOverwrite = 0;
  if (params.size() >= 3)
    bOverwrite = runtime->ToBoolean(params[2]);

  auto stream =
      pdfium::MakeRetain<CFX_ReadOnlyMemoryStream>(expression.raw_span());

  CFX_XMLParser parser(stream);
  std::unique_ptr<CFX_XMLDocument> xml_doc = parser.Parse();
  CXFA_DocumentBuilder builder(GetDocument());
  CFX_XMLNode* pXMLNode = builder.Build(xml_doc.get());
  if (!pXMLNode)
    return CJS_Result::Success();

  CFX_XMLDocument* top_xml_doc =
      GetXFANode()->GetDocument()->GetNotify()->GetFFDoc()->GetXMLDocument();
  top_xml_doc->AppendNodesFrom(xml_doc.get());

  if (bIgnoreRoot &&
      (pXMLNode->GetType() != CFX_XMLNode::Type::kElement ||
       XFA_RecognizeRichText(static_cast<CFX_XMLElement*>(pXMLNode)))) {
    bIgnoreRoot = false;
  }

  CXFA_Node* pFakeRoot = GetXFANode()->Clone(false);
  WideString wsContentType = GetCData(XFA_Attribute::ContentType);
  if (!wsContentType.IsEmpty()) {
    pFakeRoot->JSObject()->SetCData(XFA_Attribute::ContentType,
                                    WideString(wsContentType));
  }

  CFX_XMLNode* pFakeXMLRoot = pFakeRoot->GetXMLMappingNode();
  if (!pFakeXMLRoot) {
    CFX_XMLNode* pThisXMLRoot = GetXFANode()->GetXMLMappingNode();
    CFX_XMLNode* clone;
    if (pThisXMLRoot) {
      clone = pThisXMLRoot->Clone(top_xml_doc);
    } else {
      clone = top_xml_doc->CreateNode<CFX_XMLElement>(
          WideString::FromASCII(GetXFANode()->GetClassName()));
    }
    pFakeXMLRoot = clone;
  }

  if (bIgnoreRoot) {
    CFX_XMLNode* pXMLChild = pXMLNode->GetFirstChild();
    while (pXMLChild) {
      CFX_XMLNode* pXMLSibling = pXMLChild->GetNextSibling();
      pXMLNode->RemoveChild(pXMLChild);
      pFakeXMLRoot->AppendLastChild(pXMLChild);
      pXMLChild = pXMLSibling;
    }
  } else {
    pXMLNode->RemoveSelfIfParented();
    pFakeXMLRoot->AppendLastChild(pXMLNode);
  }

  builder.ConstructXFANode(pFakeRoot, pFakeXMLRoot);
  pFakeRoot = builder.GetRootNode();
  if (!pFakeRoot)
    return CJS_Result::Success();

  if (bOverwrite) {
    CXFA_Node* pChild = GetXFANode()->GetFirstChild();
    CXFA_Node* pNewChild = pFakeRoot->GetFirstChild();
    int32_t index = 0;
    while (pNewChild) {
      CXFA_Node* pItem = pNewChild->GetNextSibling();
      pFakeRoot->RemoveChildAndNotify(pNewChild, true);
      GetXFANode()->InsertChildAndNotify(index++, pNewChild);
      pNewChild->SetFlagAndNotify(XFA_NodeFlag_Initialized);
      pNewChild = pItem;
    }

    while (pChild) {
      CXFA_Node* pItem = pChild->GetNextSibling();
      GetXFANode()->RemoveChildAndNotify(pChild, true);
      pFakeRoot->InsertChildAndNotify(pChild, nullptr);
      pChild = pItem;
    }

    if (GetXFANode()->GetPacketType() == XFA_PacketType::Form &&
        GetXFANode()->GetElementType() == XFA_Element::ExData) {
      CFX_XMLNode* pTempXMLNode = GetXFANode()->GetXMLMappingNode();
      GetXFANode()->SetXMLMappingNode(pFakeXMLRoot);

      if (pTempXMLNode && !pTempXMLNode->GetParent())
        pFakeXMLRoot = pTempXMLNode;
      else
        pFakeXMLRoot = nullptr;
    }
    MoveBufferMapData(pFakeRoot, GetXFANode());
  } else {
    CXFA_Node* pChild = pFakeRoot->GetFirstChild();
    while (pChild) {
      CXFA_Node* pItem = pChild->GetNextSibling();
      pFakeRoot->RemoveChildAndNotify(pChild, true);
      GetXFANode()->InsertChildAndNotify(pChild, nullptr);
      pChild->SetFlagAndNotify(XFA_NodeFlag_Initialized);
      pChild = pItem;
    }
  }

  if (pFakeXMLRoot) {
    pFakeRoot->SetXMLMappingNode(std::move(pFakeXMLRoot));
  }
  pFakeRoot->SetFlag(XFA_NodeFlag_HasRemovedChildren);

  return CJS_Result::Success();
}

CJS_Result CJX_Node::saveFilteredXML(
    CFX_V8* runtime,
    const std::vector<v8::Local<v8::Value>>& params) {
  // TODO(weili): Check whether we need to implement this, pdfium:501.
  return CJS_Result::Success();
}

CJS_Result CJX_Node::saveXML(CFX_V8* runtime,
                             const std::vector<v8::Local<v8::Value>>& params) {
  if (params.size() > 1)
    return CJS_Result::Failure(JSMessage::kParamError);

  if (params.size() == 1 &&
      !runtime->ToWideString(params[0]).EqualsASCII("pretty")) {
    return CJS_Result::Failure(JSMessage::kValueError);
  }

  // TODO(weili): Check whether we need to save pretty print XML, pdfium:501.

  ByteString bsXMLHeader = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
  if (GetXFANode()->GetPacketType() != XFA_PacketType::Form &&
      GetXFANode()->GetPacketType() != XFA_PacketType::Datasets) {
    return CJS_Result::Success(runtime->NewString(""));
  }

  CFX_XMLNode* pElement = nullptr;
  if (GetXFANode()->GetPacketType() == XFA_PacketType::Datasets) {
    pElement = GetXFANode()->GetXMLMappingNode();
    if (!pElement || pElement->GetType() != CFX_XMLNode::Type::kElement) {
      return CJS_Result::Success(
          runtime->NewString(bsXMLHeader.AsStringView()));
    }

    XFA_DataExporter_DealWithDataGroupNode(GetXFANode());
  }

  auto pMemoryStream = pdfium::MakeRetain<CFX_MemoryStream>();
  pMemoryStream->WriteString(bsXMLHeader.AsStringView());

  if (GetXFANode()->GetPacketType() == XFA_PacketType::Form) {
    XFA_DataExporter_RegenerateFormFile(GetXFANode(), pMemoryStream, true);
  } else {
    pElement->Save(pMemoryStream);
  }

  return CJS_Result::Success(runtime->NewString(
      ByteStringView(pMemoryStream->GetBuffer(), pMemoryStream->GetSize())));
}

CJS_Result CJX_Node::setAttribute(
    CFX_V8* runtime,
    const std::vector<v8::Local<v8::Value>>& params) {
  if (params.size() != 2)
    return CJS_Result::Failure(JSMessage::kParamError);

  // Note: yes, arglist is spec'd absolutely backwards from what any sane
  // person would do, namely value first, attribute second.
  WideString attributeValue = runtime->ToWideString(params[0]);
  WideString attribute = runtime->ToWideString(params[1]);

  // Pass them to our method, however, in the more usual manner.
  SetAttributeByString(attribute.AsStringView(), attributeValue);
  return CJS_Result::Success();
}

CJS_Result CJX_Node::setElement(
    CFX_V8* runtime,
    const std::vector<v8::Local<v8::Value>>& params) {
  if (params.size() != 1 && params.size() != 2)
    return CJS_Result::Failure(JSMessage::kParamError);

  // TODO(weili): check whether we need to implement this, pdfium:501.
  return CJS_Result::Success();
}

void CJX_Node::ns(v8::Isolate* pIsolate,
                  v8::Local<v8::Value>* pValue,
                  bool bSetting,
                  XFA_Attribute eAttribute) {
  if (bSetting) {
    ThrowInvalidPropertyException();
    return;
  }
  *pValue = fxv8::NewStringHelper(
      pIsolate, TryNamespace().value_or(WideString()).ToUTF8().AsStringView());
}

void CJX_Node::model(v8::Isolate* pIsolate,
                     v8::Local<v8::Value>* pValue,
                     bool bSetting,
                     XFA_Attribute eAttribute) {
  if (bSetting) {
    ThrowInvalidPropertyException();
    return;
  }
  *pValue = GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap(
      GetXFANode()->GetModelNode());
}

void CJX_Node::isContainer(v8::Isolate* pIsolate,
                           v8::Local<v8::Value>* pValue,
                           bool bSetting,
                           XFA_Attribute eAttribute) {
  if (bSetting) {
    ThrowInvalidPropertyException();
    return;
  }
  *pValue = fxv8::NewBooleanHelper(pIsolate, GetXFANode()->IsContainerNode());
}

void CJX_Node::isNull(v8::Isolate* pIsolate,
                      v8::Local<v8::Value>* pValue,
                      bool bSetting,
                      XFA_Attribute eAttribute) {
  if (bSetting) {
    ThrowInvalidPropertyException();
    return;
  }
  if (GetXFANode()->GetElementType() == XFA_Element::Subform) {
    *pValue = fxv8::NewBooleanHelper(pIsolate, false);
    return;
  }
  *pValue = fxv8::NewBooleanHelper(pIsolate, GetContent(false).IsEmpty());
}

void CJX_Node::oneOfChild(v8::Isolate* pIsolate,
                          v8::Local<v8::Value>* pValue,
                          bool bSetting,
                          XFA_Attribute eAttribute) {
  if (bSetting) {
    ThrowInvalidPropertyException();
    return;
  }

  std::vector<CXFA_Node*> properties =
      GetXFANode()->GetNodeListWithFilter(XFA_NodeFilter_OneOfProperty);
  if (!properties.empty()) {
    *pValue = GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap(
        properties.front());
  }
}

XFA_EventError CJX_Node::execSingleEventByName(WideStringView wsEventName,
                                               XFA_Element eType) {
  CXFA_FFNotify* pNotify = GetDocument()->GetNotify();
  if (!pNotify)
    return XFA_EventError::kNotExist;

  const ExecEventParaInfo* eventParaInfo =
      GetExecEventParaInfoByName(wsEventName);
  if (!eventParaInfo)
    return XFA_EventError::kNotExist;

  switch (eventParaInfo->m_validFlags) {
    case EventAppliesTo::kNone:
      return XFA_EventError::kNotExist;
    case EventAppliesTo::kAll:
    case EventAppliesTo::kAllNonRecursive:
      return pNotify->ExecEventByDeepFirst(
          GetXFANode(), eventParaInfo->m_eventType, false,
          eventParaInfo->m_validFlags == EventAppliesTo::kAll);
    case EventAppliesTo::kSubform:
      if (eType != XFA_Element::Subform)
        return XFA_EventError::kNotExist;

      return pNotify->ExecEventByDeepFirst(
          GetXFANode(), eventParaInfo->m_eventType, false, false);
    case EventAppliesTo::kFieldOrExclusion: {
      if (eType != XFA_Element::ExclGroup && eType != XFA_Element::Field)
        return XFA_EventError::kNotExist;

      CXFA_Node* pParentNode = GetXFANode()->GetParent();
      if (pParentNode &&
          pParentNode->GetElementType() == XFA_Element::ExclGroup) {
        // TODO(dsinclair): This seems like a bug, we do the same work twice?
        pNotify->ExecEventByDeepFirst(GetXFANode(), eventParaInfo->m_eventType,
                                      false, false);
      }
      return pNotify->ExecEventByDeepFirst(
          GetXFANode(), eventParaInfo->m_eventType, false, false);
    }
    case EventAppliesTo::kField:
      if (eType != XFA_Element::Field)
        return XFA_EventError::kNotExist;

      return pNotify->ExecEventByDeepFirst(
          GetXFANode(), eventParaInfo->m_eventType, false, false);
    case EventAppliesTo::kSignature: {
      if (!GetXFANode()->IsWidgetReady())
        return XFA_EventError::kNotExist;
      if (GetXFANode()->GetUIChildNode()->GetElementType() !=
          XFA_Element::Signature) {
        return XFA_EventError::kNotExist;
      }
      return pNotify->ExecEventByDeepFirst(
          GetXFANode(), eventParaInfo->m_eventType, false, false);
    }
    case EventAppliesTo::kChoiceList: {
      if (!GetXFANode()->IsWidgetReady())
        return XFA_EventError::kNotExist;
      if (GetXFANode()->GetUIChildNode()->GetElementType() !=
          XFA_Element::ChoiceList) {
        return XFA_EventError::kNotExist;
      }
      return pNotify->ExecEventByDeepFirst(
          GetXFANode(), eventParaInfo->m_eventType, false, false);
    }
  }
  return XFA_EventError::kNotExist;
}
