// Copyright 2017 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/cjx_hostpseudomodel.h"

#include <vector>

#include "core/fxcrt/span.h"
#include "fxjs/fxv8.h"
#include "fxjs/js_resources.h"
#include "fxjs/xfa/cfxjse_engine.h"
#include "third_party/base/check.h"
#include "v8/include/v8-object.h"
#include "xfa/fxfa/cxfa_ffdoc.h"
#include "xfa/fxfa/cxfa_ffnotify.h"
#include "xfa/fxfa/parser/cscript_hostpseudomodel.h"
#include "xfa/fxfa/parser/cxfa_node.h"

namespace {

size_t FilterName(WideStringView wsExpression,
                  size_t nStart,
                  WideString& wsFilter) {
  const size_t nLength = wsExpression.GetLength();
  if (nStart >= nLength)
    return nLength;

  size_t nCount = 0;
  {
    // Span's lifetime must end before ReleaseBuffer() below.
    pdfium::span<wchar_t> pBuf = wsFilter.GetBuffer(nLength - nStart);
    const wchar_t* pSrc = wsExpression.unterminated_c_str();
    while (nStart < nLength) {
      wchar_t wCur = pSrc[nStart++];
      if (wCur == ',')
        break;

      pBuf[nCount++] = wCur;
    }
  }
  wsFilter.ReleaseBuffer(nCount);
  wsFilter.Trim();
  return nStart;
}

}  // namespace

const CJX_MethodSpec CJX_HostPseudoModel::MethodSpecs[] = {
    {"beep", beep_static},
    {"documentCountInBatch", documentCountInBatch_static},
    {"documentInBatch", documentInBatch_static},
    {"exportData", exportData_static},
    {"getFocus", getFocus_static},
    {"gotoURL", gotoURL_static},
    {"importData", importData_static},
    {"messageBox", messageBox_static},
    {"openList", openList_static},
    {"pageDown", pageDown_static},
    {"pageUp", pageUp_static},
    {"print", print_static},
    {"resetData", resetData_static},
    {"response", response_static},
    {"setFocus", setFocus_static}};

CJX_HostPseudoModel::CJX_HostPseudoModel(CScript_HostPseudoModel* model)
    : CJX_Object(model) {
  DefineMethods(MethodSpecs);
}

CJX_HostPseudoModel::~CJX_HostPseudoModel() = default;

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

void CJX_HostPseudoModel::appType(v8::Isolate* pIsolate,
                                  v8::Local<v8::Value>* pValue,
                                  bool bSetting,
                                  XFA_Attribute eAttribute) {
  CXFA_FFNotify* pNotify = GetDocument()->GetNotify();
  if (!pNotify)
    return;

  if (bSetting) {
    ThrowInvalidPropertyException(pIsolate);
    return;
  }
  *pValue = fxv8::NewStringHelper(pIsolate, "Exchange");
}

void CJX_HostPseudoModel::calculationsEnabled(v8::Isolate* pIsolate,
                                              v8::Local<v8::Value>* pValue,
                                              bool bSetting,
                                              XFA_Attribute eAttribute) {
  CXFA_FFNotify* pNotify = GetDocument()->GetNotify();
  if (!pNotify)
    return;

  CXFA_FFDoc* hDoc = pNotify->GetFFDoc();
  if (bSetting) {
    hDoc->SetCalculationsEnabled(
        fxv8::ReentrantToBooleanHelper(pIsolate, *pValue));
    return;
  }
  *pValue = fxv8::NewBooleanHelper(pIsolate, hDoc->IsCalculationsEnabled());
}

void CJX_HostPseudoModel::currentPage(v8::Isolate* pIsolate,
                                      v8::Local<v8::Value>* pValue,
                                      bool bSetting,
                                      XFA_Attribute eAttribute) {
  CXFA_FFNotify* pNotify = GetDocument()->GetNotify();
  if (!pNotify)
    return;

  CXFA_FFDoc* hDoc = pNotify->GetFFDoc();
  if (bSetting) {
    hDoc->SetCurrentPage(fxv8::ReentrantToInt32Helper(pIsolate, *pValue));
    return;
  }
  *pValue = fxv8::NewNumberHelper(pIsolate, hDoc->GetCurrentPage());
}

void CJX_HostPseudoModel::language(v8::Isolate* pIsolate,
                                   v8::Local<v8::Value>* pValue,
                                   bool bSetting,
                                   XFA_Attribute eAttribute) {
  CXFA_FFNotify* pNotify = GetDocument()->GetNotify();
  if (!pNotify)
    return;

  if (bSetting) {
    ThrowException(pIsolate,
                   WideString::FromASCII("Unable to set language value."));
    return;
  }
  ByteString lang = pNotify->GetAppProvider()->GetLanguage().ToUTF8();
  *pValue = fxv8::NewStringHelper(pIsolate, lang.AsStringView());
}

void CJX_HostPseudoModel::numPages(v8::Isolate* pIsolate,
                                   v8::Local<v8::Value>* pValue,
                                   bool bSetting,
                                   XFA_Attribute eAttribute) {
  CXFA_FFNotify* pNotify = GetDocument()->GetNotify();
  if (!pNotify)
    return;

  CXFA_FFDoc* hDoc = pNotify->GetFFDoc();
  if (bSetting) {
    ThrowException(pIsolate,
                   WideString::FromASCII("Unable to set numPages value."));
    return;
  }
  *pValue = fxv8::NewNumberHelper(pIsolate, hDoc->CountPages());
}

void CJX_HostPseudoModel::platform(v8::Isolate* pIsolate,
                                   v8::Local<v8::Value>* pValue,
                                   bool bSetting,
                                   XFA_Attribute eAttribute) {
  CXFA_FFNotify* pNotify = GetDocument()->GetNotify();
  if (!pNotify)
    return;

  if (bSetting) {
    ThrowException(pIsolate,
                   WideString::FromASCII("Unable to set platform value."));
    return;
  }
  ByteString plat = pNotify->GetAppProvider()->GetPlatform().ToUTF8();
  *pValue = fxv8::NewStringHelper(pIsolate, plat.AsStringView());
}

void CJX_HostPseudoModel::title(v8::Isolate* pIsolate,
                                v8::Local<v8::Value>* pValue,
                                bool bSetting,
                                XFA_Attribute eAttribute) {
  if (!GetDocument()->GetScriptContext()->IsRunAtClient())
    return;

  CXFA_FFNotify* pNotify = GetDocument()->GetNotify();
  if (!pNotify)
    return;

  CXFA_FFDoc* hDoc = pNotify->GetFFDoc();
  if (bSetting) {
    hDoc->SetTitle(fxv8::ReentrantToWideStringHelper(pIsolate, *pValue));
    return;
  }

  ByteString bsTitle = hDoc->GetTitle().ToUTF8();
  *pValue = fxv8::NewStringHelper(pIsolate, bsTitle.AsStringView());
}

void CJX_HostPseudoModel::validationsEnabled(v8::Isolate* pIsolate,
                                             v8::Local<v8::Value>* pValue,
                                             bool bSetting,
                                             XFA_Attribute eAttribute) {
  CXFA_FFNotify* pNotify = GetDocument()->GetNotify();
  if (!pNotify)
    return;

  CXFA_FFDoc* hDoc = pNotify->GetFFDoc();
  if (bSetting) {
    hDoc->SetValidationsEnabled(
        fxv8::ReentrantToBooleanHelper(pIsolate, *pValue));
    return;
  }

  *pValue = fxv8::NewBooleanHelper(pIsolate, hDoc->IsValidationsEnabled());
}

void CJX_HostPseudoModel::variation(v8::Isolate* pIsolate,
                                    v8::Local<v8::Value>* pValue,
                                    bool bSetting,
                                    XFA_Attribute eAttribute) {
  if (!GetDocument()->GetScriptContext()->IsRunAtClient())
    return;

  if (bSetting) {
    ThrowException(pIsolate,
                   WideString::FromASCII("Unable to set variation value."));
    return;
  }
  *pValue = fxv8::NewStringHelper(pIsolate, "Full");
}

void CJX_HostPseudoModel::version(v8::Isolate* pIsolate,
                                  v8::Local<v8::Value>* pValue,
                                  bool bSetting,
                                  XFA_Attribute eAttribute) {
  if (bSetting) {
    ThrowException(pIsolate,
                   WideString::FromASCII("Unable to set version value."));
    return;
  }
  *pValue = fxv8::NewStringHelper(pIsolate, "11");
}

void CJX_HostPseudoModel::name(v8::Isolate* pIsolate,
                               v8::Local<v8::Value>* pValue,
                               bool bSetting,
                               XFA_Attribute eAttribute) {
  CXFA_FFNotify* pNotify = GetDocument()->GetNotify();
  if (!pNotify)
    return;

  if (bSetting) {
    ThrowInvalidPropertyException(pIsolate);
    return;
  }
  ByteString bsName = pNotify->GetAppProvider()->GetAppName().ToUTF8();
  *pValue = fxv8::NewStringHelper(pIsolate, bsName.AsStringView());
}

CJS_Result CJX_HostPseudoModel::gotoURL(
    CFXJSE_Engine* runtime,
    pdfium::span<v8::Local<v8::Value>> params) {
  if (!runtime->IsRunAtClient()) {
    return CJS_Result::Success();
  }

  if (params.size() != 1)
    return CJS_Result::Failure(JSMessage::kParamError);

  CXFA_FFNotify* pNotify = GetDocument()->GetNotify();
  if (!pNotify)
    return CJS_Result::Success();

  pNotify->GetFFDoc()->GotoURL(runtime->ToWideString(params[0]));
  return CJS_Result::Success();
}

CJS_Result CJX_HostPseudoModel::openList(
    CFXJSE_Engine* runtime,
    pdfium::span<v8::Local<v8::Value>> params) {
  if (!runtime->IsRunAtClient()) {
    return CJS_Result::Success();
  }

  if (params.size() != 1)
    return CJS_Result::Failure(JSMessage::kParamError);

  CXFA_FFNotify* pNotify = GetDocument()->GetNotify();
  if (!pNotify)
    return CJS_Result::Success();

  CXFA_Node* pNode = nullptr;
  if (params[0]->IsObject()) {
    pNode = ToNode(runtime->ToXFAObject(params[0]));
  } else if (params[0]->IsString()) {
    CXFA_Object* pObject = runtime->GetThisObject();
    if (!pObject)
      return CJS_Result::Success();

    constexpr Mask<XFA_ResolveFlag> kFlags = {XFA_ResolveFlag::kChildren,
                                              XFA_ResolveFlag::kParent,
                                              XFA_ResolveFlag::kSiblings};
    std::optional<CFXJSE_Engine::ResolveResult> maybeResult =
        runtime->ResolveObjects(
            pObject, runtime->ToWideString(params[0]).AsStringView(), kFlags);
    if (!maybeResult.has_value() ||
        !maybeResult.value().objects.front()->IsNode()) {
      return CJS_Result::Success();
    }
    pNode = maybeResult.value().objects.front()->AsNode();
  }
  if (pNode)
    pNotify->OpenDropDownList(pNode);

  return CJS_Result::Success();
}

CJS_Result CJX_HostPseudoModel::response(
    CFXJSE_Engine* runtime,
    pdfium::span<v8::Local<v8::Value>> params) {
  if (params.empty() || params.size() > 4)
    return CJS_Result::Failure(JSMessage::kParamError);

  CXFA_FFNotify* pNotify = GetDocument()->GetNotify();
  if (!pNotify)
    return CJS_Result::Success();

  WideString question;
  if (params.size() >= 1)
    question = runtime->ToWideString(params[0]);

  WideString title;
  if (params.size() >= 2)
    title = runtime->ToWideString(params[1]);

  WideString defaultAnswer;
  if (params.size() >= 3)
    defaultAnswer = runtime->ToWideString(params[2]);

  bool mark = false;
  if (params.size() >= 4)
    mark = runtime->ToInt32(params[3]) != 0;

  WideString answer =
      pNotify->GetAppProvider()->Response(question, title, defaultAnswer, mark);
  return CJS_Result::Success(
      runtime->NewString(answer.ToUTF8().AsStringView()));
}

CJS_Result CJX_HostPseudoModel::documentInBatch(
    CFXJSE_Engine* runtime,
    pdfium::span<v8::Local<v8::Value>> params) {
  return CJS_Result::Success(runtime->NewNumber(0));
}

CJS_Result CJX_HostPseudoModel::resetData(
    CFXJSE_Engine* runtime,
    pdfium::span<v8::Local<v8::Value>> params) {
  if (params.size() > 1)
    return CJS_Result::Failure(JSMessage::kParamError);

  CXFA_FFNotify* pNotify = GetDocument()->GetNotify();
  if (!pNotify)
    return CJS_Result::Success();

  WideString expression;
  if (params.size() >= 1)
    expression = runtime->ToWideString(params[0]);

  if (expression.IsEmpty()) {
    pNotify->ResetData(nullptr);
    return CJS_Result::Success();
  }

  WideString wsName;
  CXFA_Node* pNode = nullptr;
  size_t nStart = 0;
  const size_t nExpLength = expression.GetLength();
  while (nStart < nExpLength) {
    nStart = FilterName(expression.AsStringView(), nStart, wsName);
    CXFA_Object* pObject = runtime->GetThisObject();
    if (!pObject)
      return CJS_Result::Success();

    constexpr Mask<XFA_ResolveFlag> kFlags = {XFA_ResolveFlag::kChildren,
                                              XFA_ResolveFlag::kParent,
                                              XFA_ResolveFlag::kSiblings};
    std::optional<CFXJSE_Engine::ResolveResult> maybeResult =
        runtime->ResolveObjects(pObject, wsName.AsStringView(), kFlags);
    if (!maybeResult.has_value() ||
        !maybeResult.value().objects.front()->IsNode())
      continue;

    pNode = maybeResult.value().objects.front()->AsNode();
    pNotify->ResetData(pNode->IsWidgetReady() ? pNode : nullptr);
  }
  if (!pNode)
    pNotify->ResetData(nullptr);

  return CJS_Result::Success();
}

CJS_Result CJX_HostPseudoModel::beep(
    CFXJSE_Engine* runtime,
    pdfium::span<v8::Local<v8::Value>> params) {
  if (!runtime->IsRunAtClient()) {
    return CJS_Result::Success();
  }

  if (params.size() > 1)
    return CJS_Result::Failure(JSMessage::kParamError);

  CXFA_FFNotify* pNotify = GetDocument()->GetNotify();
  if (!pNotify)
    return CJS_Result::Success();

  uint32_t dwType = 4;
  if (params.size() >= 1)
    dwType = runtime->ToInt32(params[0]);

  pNotify->GetAppProvider()->Beep(dwType);
  return CJS_Result::Success();
}

CJS_Result CJX_HostPseudoModel::setFocus(
    CFXJSE_Engine* runtime,
    pdfium::span<v8::Local<v8::Value>> params) {
  if (!runtime->IsRunAtClient()) {
    return CJS_Result::Success();
  }

  if (params.size() != 1)
    return CJS_Result::Failure(JSMessage::kParamError);

  CXFA_FFNotify* pNotify = GetDocument()->GetNotify();
  if (!pNotify)
    return CJS_Result::Success();

  CXFA_Node* pNode = nullptr;
  if (params.size() >= 1) {
    if (params[0]->IsObject()) {
      pNode = ToNode(runtime->ToXFAObject(params[0]));
    } else if (params[0]->IsString()) {
      CXFA_Object* pObject = runtime->GetThisObject();
      if (!pObject)
        return CJS_Result::Success();

      constexpr Mask<XFA_ResolveFlag> kFlags = {XFA_ResolveFlag::kChildren,
                                                XFA_ResolveFlag::kParent,
                                                XFA_ResolveFlag::kSiblings};
      std::optional<CFXJSE_Engine::ResolveResult> maybeResult =
          runtime->ResolveObjects(
              pObject, runtime->ToWideString(params[0]).AsStringView(), kFlags);
      if (!maybeResult.has_value() ||
          !maybeResult.value().objects.front()->IsNode()) {
        return CJS_Result::Success();
      }
      pNode = maybeResult.value().objects.front()->AsNode();
    }
  }
  pNotify->SetFocusWidgetNode(pNode);
  return CJS_Result::Success();
}

CJS_Result CJX_HostPseudoModel::getFocus(
    CFXJSE_Engine* runtime,
    pdfium::span<v8::Local<v8::Value>> params) {
  CXFA_FFNotify* pNotify = GetDocument()->GetNotify();
  if (!pNotify)
    return CJS_Result::Success();

  CXFA_Node* pNode = pNotify->GetFocusWidgetNode();
  if (!pNode)
    return CJS_Result::Success();

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

CJS_Result CJX_HostPseudoModel::messageBox(
    CFXJSE_Engine* runtime,
    pdfium::span<v8::Local<v8::Value>> params) {
  if (!runtime->IsRunAtClient()) {
    return CJS_Result::Success();
  }

  if (params.empty() || params.size() > 4)
    return CJS_Result::Failure(JSMessage::kParamError);

  CXFA_FFNotify* pNotify = GetDocument()->GetNotify();
  if (!pNotify)
    return CJS_Result::Success();

  WideString message;
  if (params.size() >= 1)
    message = runtime->ToWideString(params[0]);

  WideString title;
  if (params.size() >= 2)
    title = runtime->ToWideString(params[1]);

  uint32_t messageType = static_cast<uint32_t>(AlertIcon::kDefault);
  if (params.size() >= 3) {
    messageType = runtime->ToInt32(params[2]);
    if (messageType > static_cast<uint32_t>(AlertIcon::kStatus))
      messageType = static_cast<uint32_t>(AlertIcon::kDefault);
  }

  uint32_t buttonType = static_cast<uint32_t>(AlertButton::kDefault);
  if (params.size() >= 4) {
    buttonType = runtime->ToInt32(params[3]);
    if (buttonType > static_cast<uint32_t>(AlertButton::kYesNoCancel))
      buttonType = static_cast<uint32_t>(AlertButton::kDefault);
  }

  int32_t iValue = pNotify->GetAppProvider()->MsgBox(message, title,
                                                     messageType, buttonType);
  return CJS_Result::Success(runtime->NewNumber(iValue));
}

CJS_Result CJX_HostPseudoModel::documentCountInBatch(
    CFXJSE_Engine* runtime,
    pdfium::span<v8::Local<v8::Value>> params) {
  return CJS_Result::Success(runtime->NewNumber(0));
}

CJS_Result CJX_HostPseudoModel::print(
    CFXJSE_Engine* runtime,
    pdfium::span<v8::Local<v8::Value>> params) {
  if (!runtime->IsRunAtClient()) {
    return CJS_Result::Success();
  }

  if (params.size() != 8)
    return CJS_Result::Failure(JSMessage::kParamError);

  CXFA_FFNotify* pNotify = GetDocument()->GetNotify();
  if (!pNotify)
    return CJS_Result::Success();

  Mask<XFA_PrintOpt> dwOptions;
  if (runtime->ToBoolean(params[0]))
    dwOptions |= XFA_PrintOpt::kShowDialog;
  if (runtime->ToBoolean(params[3]))
    dwOptions |= XFA_PrintOpt::kCanCancel;
  if (runtime->ToBoolean(params[4]))
    dwOptions |= XFA_PrintOpt::kShrinkPage;
  if (runtime->ToBoolean(params[5]))
    dwOptions |= XFA_PrintOpt::kAsImage;
  if (runtime->ToBoolean(params[6]))
    dwOptions |= XFA_PrintOpt::kReverseOrder;
  if (runtime->ToBoolean(params[7]))
    dwOptions |= XFA_PrintOpt::kPrintAnnot;

  int32_t nStartPage = runtime->ToInt32(params[1]);
  int32_t nEndPage = runtime->ToInt32(params[2]);
  pNotify->GetFFDoc()->Print(nStartPage, nEndPage, dwOptions);
  return CJS_Result::Success();
}

CJS_Result CJX_HostPseudoModel::importData(
    CFXJSE_Engine* runtime,
    pdfium::span<v8::Local<v8::Value>> params) {
  if (params.empty() || params.size() > 1)
    return CJS_Result::Failure(JSMessage::kParamError);

  return CJS_Result::Success();
}

CJS_Result CJX_HostPseudoModel::exportData(
    CFXJSE_Engine* runtime,
    pdfium::span<v8::Local<v8::Value>> params) {
  if (params.empty() || params.size() > 2)
    return CJS_Result::Failure(JSMessage::kParamError);

  CXFA_FFNotify* pNotify = GetDocument()->GetNotify();
  if (!pNotify)
    return CJS_Result::Success();

  WideString filePath;
  if (params.size() >= 1)
    filePath = runtime->ToWideString(params[0]);

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

  pNotify->GetFFDoc()->ExportData(filePath, XDP);
  return CJS_Result::Success();
}

CJS_Result CJX_HostPseudoModel::pageUp(
    CFXJSE_Engine* runtime,
    pdfium::span<v8::Local<v8::Value>> params) {
  CXFA_FFNotify* pNotify = GetDocument()->GetNotify();
  if (!pNotify)
    return CJS_Result::Success();

  CXFA_FFDoc* hDoc = pNotify->GetFFDoc();
  int32_t nCurPage = hDoc->GetCurrentPage();
  if (nCurPage <= 1)
    return CJS_Result::Success();

  hDoc->SetCurrentPage(nCurPage - 1);
  return CJS_Result::Success();
}

CJS_Result CJX_HostPseudoModel::pageDown(
    CFXJSE_Engine* runtime,
    pdfium::span<v8::Local<v8::Value>> params) {
  CXFA_FFNotify* pNotify = GetDocument()->GetNotify();
  if (!pNotify)
    return CJS_Result::Success();

  CXFA_FFDoc* hDoc = pNotify->GetFFDoc();
  int32_t nCurPage = hDoc->GetCurrentPage();
  int32_t nPageCount = hDoc->CountPages();
  if (!nPageCount || nCurPage == nPageCount)
    return CJS_Result::Success();

  int32_t nNewPage = 0;
  if (nCurPage >= nPageCount)
    nNewPage = nPageCount - 1;
  else
    nNewPage = nCurPage + 1;

  hDoc->SetCurrentPage(nNewPage);
  return CJS_Result::Success();
}
