// Copyright 2016 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/cxfa_validatedata.h"

#include "xfa/fxfa/parser/cxfa_node.h"
#include "xfa/fxfa/parser/xfa_utils.h"

CXFA_ValidateData::CXFA_ValidateData(CXFA_Node* pNode) : CXFA_Data(pNode) {}

int32_t CXFA_ValidateData::GetFormatTest() {
  return m_pNode->JSNode()->GetEnum(XFA_ATTRIBUTE_FormatTest);
}

bool CXFA_ValidateData::SetNullTest(WideString wsValue) {
  const XFA_ATTRIBUTEENUMINFO* pInfo =
      XFA_GetAttributeEnumByName(wsValue.AsStringView());
  m_pNode->JSNode()->SetEnum(XFA_ATTRIBUTE_NullTest,
                             pInfo ? pInfo->eName : XFA_ATTRIBUTEENUM_Disabled,
                             false);
  return true;
}

int32_t CXFA_ValidateData::GetNullTest() {
  return m_pNode->JSNode()->GetEnum(XFA_ATTRIBUTE_NullTest);
}

int32_t CXFA_ValidateData::GetScriptTest() {
  return m_pNode->JSNode()->GetEnum(XFA_ATTRIBUTE_ScriptTest);
}

void CXFA_ValidateData::GetMessageText(WideString& wsMessage,
                                       const WideString& wsMessageType) {
  CXFA_Node* pNode =
      m_pNode->JSNode()->GetProperty(0, XFA_Element::Message, false);
  if (!pNode)
    return;

  CXFA_Node* pItemNode = pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
  for (; pItemNode;
       pItemNode = pItemNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
    if (pItemNode->GetElementType() != XFA_Element::Text)
      continue;

    WideStringView wsName;
    pItemNode->JSNode()->TryCData(XFA_ATTRIBUTE_Name, wsName, true);
    if (wsName.IsEmpty() || wsName == wsMessageType) {
      pItemNode->JSNode()->TryContent(wsMessage, false, true);
      return;
    }
  }
}

void CXFA_ValidateData::SetFormatMessageText(WideString wsMessage) {
  SetMessageText(wsMessage, L"formatTest");
}

void CXFA_ValidateData::GetFormatMessageText(WideString& wsMessage) {
  GetMessageText(wsMessage, L"formatTest");
}

void CXFA_ValidateData::SetNullMessageText(WideString wsMessage) {
  SetMessageText(wsMessage, L"nullTest");
}

void CXFA_ValidateData::GetNullMessageText(WideString& wsMessage) {
  GetMessageText(wsMessage, L"nullTest");
}

void CXFA_ValidateData::SetMessageText(WideString& wsMessage,
                                       const WideString& wsMessageType) {
  CXFA_Node* pNode =
      m_pNode->JSNode()->GetProperty(0, XFA_Element::Message, true);
  if (!pNode)
    return;

  CXFA_Node* pItemNode = pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
  for (; pItemNode;
       pItemNode = pItemNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
    if (pItemNode->GetElementType() != XFA_Element::Text)
      continue;

    WideStringView wsName;
    pItemNode->JSNode()->TryCData(XFA_ATTRIBUTE_Name, wsName, true);
    if (wsName.IsEmpty() || wsName == wsMessageType) {
      pItemNode->JSNode()->SetContent(wsMessage, wsMessage, false, false, true);
      return;
    }
  }
  CXFA_Node* pTextNode = pNode->CreateSamePacketNode(XFA_Element::Text);
  pNode->InsertChild(pTextNode, nullptr);
  pTextNode->JSNode()->SetCData(XFA_ATTRIBUTE_Name, wsMessageType, false,
                                false);
  pTextNode->JSNode()->SetContent(wsMessage, wsMessage, false, false, true);
}

void CXFA_ValidateData::GetScriptMessageText(WideString& wsMessage) {
  GetMessageText(wsMessage, L"scriptTest");
}

void CXFA_ValidateData::SetScriptMessageText(WideString wsMessage) {
  SetMessageText(wsMessage, L"scriptTest");
}

void CXFA_ValidateData::GetPicture(WideString& wsPicture) {
  if (CXFA_Node* pNode = m_pNode->GetChild(0, XFA_Element::Picture, false))
    pNode->JSNode()->TryContent(wsPicture, false, true);
}

CXFA_ScriptData CXFA_ValidateData::GetScriptData() {
  return CXFA_ScriptData(m_pNode->GetChild(0, XFA_Element::Script, false));
}
