// 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/fm2js/cxfa_fmexpression.h"

#include <utility>

#include "core/fxcrt/cfx_widetextbuf.h"
#include "xfa/fxfa/fm2js/cxfa_fmsimpleexpression.h"
#include "xfa/fxfa/fm2js/cxfa_fmtojavascriptdepth.h"

namespace {

const wchar_t kLessEqual[] = L" <= ";
const wchar_t kGreaterEqual[] = L" >= ";
const wchar_t kPlusEqual[] = L" += ";
const wchar_t kMinusEqual[] = L" -= ";

}  // namespace

CXFA_FMExpression::CXFA_FMExpression() = default;

CXFA_FMFunctionDefinition::CXFA_FMFunctionDefinition(
    bool isGlobal,
    const WideStringView& wsName,
    std::vector<WideStringView>&& arguments,
    std::vector<std::unique_ptr<CXFA_FMExpression>>&& expressions)
    : CXFA_FMExpression(),
      m_wsName(wsName),
      m_pArguments(std::move(arguments)),
      m_pExpressions(std::move(expressions)),
      m_isGlobal(isGlobal) {}

CXFA_FMFunctionDefinition::~CXFA_FMFunctionDefinition() = default;

bool CXFA_FMFunctionDefinition::ToJavaScript(CFX_WideTextBuf& js,
                                             ReturnType type) {
  CXFA_FMToJavaScriptDepth depthManager;
  if (type == ReturnType::kImplied)
    return !CXFA_IsTooBig(js) && depthManager.IsWithinMaxDepth();

  if (CXFA_IsTooBig(js) || !depthManager.IsWithinMaxDepth())
    return false;

  if (m_isGlobal && m_pExpressions.empty()) {
    js << L"// comments only";
    return !CXFA_IsTooBig(js);
  }
  if (m_isGlobal)
    js << L"(\n";

  js << L"function ";
  if (!m_wsName.IsEmpty() && m_wsName[0] == L'!') {
    WideString tempName =
        L"pfm__excl__" + m_wsName.Right(m_wsName.GetLength() - 1);
    js << tempName;
  } else {
    js << m_wsName;
  }

  js << L"(";
  bool bNeedComma = false;
  for (const auto& identifier : m_pArguments) {
    if (bNeedComma)
      js << L", ";
    if (identifier[0] == L'!') {
      WideString tempIdentifier =
          L"pfm__excl__" + identifier.Right(identifier.GetLength() - 1);
      js << tempIdentifier;
    } else {
      js << identifier;
    }
    bNeedComma = true;
  }
  js << L")\n{\n";

  js << L"var pfm_ret = null;\n";
  for (const auto& expr : m_pExpressions) {
    ReturnType ret_type = expr == m_pExpressions.back() ? ReturnType::kImplied
                                                        : ReturnType::kInfered;
    if (!expr->ToJavaScript(js, ret_type))
      return false;
  }

  js << L"return ";
  if (m_isGlobal)
    js << L"pfm_rt.get_val(pfm_ret);\n";
  else
    js << L"pfm_ret;\n";

  js << L"}\n";
  if (m_isGlobal)
    js << L").call(this);\n";

  return !CXFA_IsTooBig(js);
}

CXFA_FMVarExpression::CXFA_FMVarExpression(
    const WideStringView& wsName,
    std::unique_ptr<CXFA_FMSimpleExpression> pInit)
    : CXFA_FMExpression(), m_wsName(wsName), m_pInit(std::move(pInit)) {}

CXFA_FMVarExpression::~CXFA_FMVarExpression() = default;

bool CXFA_FMVarExpression::ToJavaScript(CFX_WideTextBuf& js, ReturnType type) {
  CXFA_FMToJavaScriptDepth depthManager;
  if (CXFA_IsTooBig(js) || !depthManager.IsWithinMaxDepth())
    return false;

  WideString tempName(m_wsName);
  if (m_wsName[0] == L'!')
    tempName = L"pfm__excl__" + m_wsName.Right(m_wsName.GetLength() - 1);

  js << L"var " << tempName << L" = ";
  if (m_pInit) {
    if (!m_pInit->ToJavaScript(js, ReturnType::kInfered))
      return false;

    js << tempName << L" = pfm_rt.var_filter(" << tempName << L");\n";
  } else {
    js << L"\"\";\n";
  }

  if (type == ReturnType::kImplied)
    js << L"pfm_ret = " << tempName << L";\n";

  return !CXFA_IsTooBig(js);
}

CXFA_FMExpExpression::CXFA_FMExpExpression(
    std::unique_ptr<CXFA_FMSimpleExpression> pExpression)
    : CXFA_FMExpression(), m_pExpression(std::move(pExpression)) {}

CXFA_FMExpExpression::~CXFA_FMExpExpression() = default;

bool CXFA_FMExpExpression::ToJavaScript(CFX_WideTextBuf& js, ReturnType type) {
  CXFA_FMToJavaScriptDepth depthManager;
  if (CXFA_IsTooBig(js) || !depthManager.IsWithinMaxDepth())
    return false;

  if (type == ReturnType::kInfered) {
    bool ret = m_pExpression->ToJavaScript(js, ReturnType::kInfered);
    if (m_pExpression->GetOperatorToken() != TOKassign)
      js << L";\n";

    return ret;
  }

  if (m_pExpression->GetOperatorToken() == TOKassign)
    return m_pExpression->ToJavaScript(js, ReturnType::kImplied);

  if (m_pExpression->GetOperatorToken() == TOKstar ||
      m_pExpression->GetOperatorToken() == TOKdotstar ||
      m_pExpression->GetOperatorToken() == TOKdotscream ||
      m_pExpression->GetOperatorToken() == TOKdotdot ||
      m_pExpression->GetOperatorToken() == TOKdot) {
    js << L"pfm_ret = pfm_rt.get_val(";
    if (!m_pExpression->ToJavaScript(js, ReturnType::kInfered))
      return false;

    js << L");\n";
    return !CXFA_IsTooBig(js);
  }

  js << L"pfm_ret = ";
  if (!m_pExpression->ToJavaScript(js, ReturnType::kInfered))
    return false;

  js << L";\n";
  return !CXFA_IsTooBig(js);
}

CXFA_FMBlockExpression::CXFA_FMBlockExpression(
    std::vector<std::unique_ptr<CXFA_FMExpression>>&& pExpressionList)
    : CXFA_FMExpression(), m_ExpressionList(std::move(pExpressionList)) {}

CXFA_FMBlockExpression::~CXFA_FMBlockExpression() = default;

bool CXFA_FMBlockExpression::ToJavaScript(CFX_WideTextBuf& js,
                                          ReturnType type) {
  CXFA_FMToJavaScriptDepth depthManager;
  if (CXFA_IsTooBig(js) || !depthManager.IsWithinMaxDepth())
    return false;

  js << L"{\n";
  for (const auto& expr : m_ExpressionList) {
    if (type == ReturnType::kInfered) {
      if (!expr->ToJavaScript(js, ReturnType::kInfered))
        return false;
    } else {
      ReturnType ret_type = expr == m_ExpressionList.back()
                                ? ReturnType::kImplied
                                : ReturnType::kInfered;
      if (!expr->ToJavaScript(js, ret_type))
        return false;
    }
  }
  js << L"}\n";

  return !CXFA_IsTooBig(js);
}

CXFA_FMDoExpression::CXFA_FMDoExpression(
    std::unique_ptr<CXFA_FMExpression> pList)
    : CXFA_FMExpression(), m_pList(std::move(pList)) {}

CXFA_FMDoExpression::~CXFA_FMDoExpression() = default;

bool CXFA_FMDoExpression::ToJavaScript(CFX_WideTextBuf& js, ReturnType type) {
  CXFA_FMToJavaScriptDepth depthManager;
  if (CXFA_IsTooBig(js) || !depthManager.IsWithinMaxDepth())
    return false;

  return m_pList->ToJavaScript(js, type);
}

CXFA_FMIfExpression::CXFA_FMIfExpression(
    std::unique_ptr<CXFA_FMSimpleExpression> pExpression,
    std::unique_ptr<CXFA_FMExpression> pIfExpression,
    std::unique_ptr<CXFA_FMExpression> pElseExpression)
    : CXFA_FMExpression(),
      m_pExpression(std::move(pExpression)),
      m_pIfExpression(std::move(pIfExpression)),
      m_pElseExpression(std::move(pElseExpression)) {}

CXFA_FMIfExpression::~CXFA_FMIfExpression() = default;

bool CXFA_FMIfExpression::ToJavaScript(CFX_WideTextBuf& js, ReturnType type) {
  CXFA_FMToJavaScriptDepth depthManager;
  if (CXFA_IsTooBig(js) || !depthManager.IsWithinMaxDepth())
    return false;

  if (type == ReturnType::kImplied)
    js << L"pfm_ret = 0;\n";

  js << L"if (";
  if (m_pExpression) {
    js << L"pfm_rt.get_val(";
    if (!m_pExpression->ToJavaScript(js, ReturnType::kInfered))
      return false;

    js << L")";
  }
  js << L")\n";

  if (CXFA_IsTooBig(js))
    return false;

  if (m_pIfExpression) {
    if (!m_pIfExpression->ToJavaScript(js, type))
      return false;
    if (CXFA_IsTooBig(js))
      return false;
  }

  if (m_pElseExpression) {
    js << L"else\n{\n";
    if (!m_pElseExpression->ToJavaScript(js, type))
      return false;
    js << L"}\n";
  }
  return !CXFA_IsTooBig(js);
}

CXFA_FMWhileExpression::CXFA_FMWhileExpression(
    std::unique_ptr<CXFA_FMSimpleExpression> pCondition,
    std::unique_ptr<CXFA_FMExpression> pExpression)
    : CXFA_FMExpression(),
      m_pCondition(std::move(pCondition)),
      m_pExpression(std::move(pExpression)) {}

CXFA_FMWhileExpression::~CXFA_FMWhileExpression() = default;

bool CXFA_FMWhileExpression::ToJavaScript(CFX_WideTextBuf& js,
                                          ReturnType type) {
  CXFA_FMToJavaScriptDepth depthManager;
  if (CXFA_IsTooBig(js) || !depthManager.IsWithinMaxDepth())
    return false;

  if (type == ReturnType::kImplied)
    js << L"pfm_ret = 0;\n";

  js << L"while (";
  if (!m_pCondition->ToJavaScript(js, ReturnType::kInfered))
    return false;

  js << L")\n";
  if (CXFA_IsTooBig(js))
    return false;

  if (!m_pExpression->ToJavaScript(js, type))
    return false;

  return !CXFA_IsTooBig(js);
}

CXFA_FMBreakExpression::CXFA_FMBreakExpression() : CXFA_FMExpression() {}

CXFA_FMBreakExpression::~CXFA_FMBreakExpression() = default;

bool CXFA_FMBreakExpression::ToJavaScript(CFX_WideTextBuf& js,
                                          ReturnType type) {
  CXFA_FMToJavaScriptDepth depthManager;
  if (CXFA_IsTooBig(js) || !depthManager.IsWithinMaxDepth())
    return false;

  js << L"pfm_ret = 0;\nbreak;\n";
  return !CXFA_IsTooBig(js);
}

CXFA_FMContinueExpression::CXFA_FMContinueExpression() : CXFA_FMExpression() {}

CXFA_FMContinueExpression::~CXFA_FMContinueExpression() = default;

bool CXFA_FMContinueExpression::ToJavaScript(CFX_WideTextBuf& js,
                                             ReturnType type) {
  CXFA_FMToJavaScriptDepth depthManager;
  if (CXFA_IsTooBig(js) || !depthManager.IsWithinMaxDepth())
    return false;

  js << L"pfm_ret = 0;\ncontinue;\n";
  return !CXFA_IsTooBig(js);
}

CXFA_FMForExpression::CXFA_FMForExpression(
    const WideStringView& wsVariant,
    std::unique_ptr<CXFA_FMSimpleExpression> pAssignment,
    std::unique_ptr<CXFA_FMSimpleExpression> pAccessor,
    int32_t iDirection,
    std::unique_ptr<CXFA_FMSimpleExpression> pStep,
    std::unique_ptr<CXFA_FMExpression> pList)
    : CXFA_FMExpression(),
      m_wsVariant(wsVariant),
      m_pAssignment(std::move(pAssignment)),
      m_pAccessor(std::move(pAccessor)),
      m_bDirection(iDirection == 1),
      m_pStep(std::move(pStep)),
      m_pList(std::move(pList)) {}

CXFA_FMForExpression::~CXFA_FMForExpression() = default;

bool CXFA_FMForExpression::ToJavaScript(CFX_WideTextBuf& js, ReturnType type) {
  CXFA_FMToJavaScriptDepth depthManager;
  if (CXFA_IsTooBig(js) || !depthManager.IsWithinMaxDepth())
    return false;

  if (type == ReturnType::kImplied)
    js << L"pfm_ret = 0;\n";

  js << L"{\n";

  WideString tmpName;
  if (m_wsVariant[0] == L'!')
    tmpName = L"pfm__excl__" + m_wsVariant.Right(m_wsVariant.GetLength() - 1);
  else
    tmpName = m_wsVariant;

  js << L"var " << tmpName << L" = null;\n";

  CFX_WideTextBuf assign_txt;
  if (!m_pAssignment->ToJavaScript(assign_txt, ReturnType::kInfered))
    return false;

  CFX_WideTextBuf accessor_txt;
  if (!m_pAccessor->ToJavaScript(accessor_txt, ReturnType::kInfered))
    return false;

  js << L"for (" << tmpName << L" = pfm_rt.get_val(" << assign_txt << L"); ";
  js << tmpName << (m_bDirection ? kLessEqual : kGreaterEqual);
  js << L"pfm_rt.get_val(" << accessor_txt << L"); ";
  js << tmpName << (m_bDirection ? kPlusEqual : kMinusEqual);
  if (m_pStep) {
    CFX_WideTextBuf step_txt;
    if (!m_pStep->ToJavaScript(step_txt, ReturnType::kInfered))
      return false;

    js << L"pfm_rt.get_val(" << step_txt << L")";
  } else {
    js << L"1";
  }
  js << L")\n";
  if (CXFA_IsTooBig(js))
    return false;

  if (!m_pList->ToJavaScript(js, type))
    return false;

  js << L"}\n";
  return !CXFA_IsTooBig(js);
}

CXFA_FMForeachExpression::CXFA_FMForeachExpression(
    const WideStringView& wsIdentifier,
    std::vector<std::unique_ptr<CXFA_FMSimpleExpression>>&& pAccessors,
    std::unique_ptr<CXFA_FMExpression> pList)
    : CXFA_FMExpression(),
      m_wsIdentifier(wsIdentifier),
      m_pAccessors(std::move(pAccessors)),
      m_pList(std::move(pList)) {}

CXFA_FMForeachExpression::~CXFA_FMForeachExpression() = default;

bool CXFA_FMForeachExpression::ToJavaScript(CFX_WideTextBuf& js,
                                            ReturnType type) {
  CXFA_FMToJavaScriptDepth depthManager;
  if (CXFA_IsTooBig(js) || !depthManager.IsWithinMaxDepth())
    return false;

  if (type == ReturnType::kImplied)
    js << L"pfm_ret = 0;\n";

  js << L"{\n";

  WideString tmpName;
  if (m_wsIdentifier[0] == L'!') {
    tmpName =
        L"pfm__excl__" + m_wsIdentifier.Right(m_wsIdentifier.GetLength() - 1);
  } else {
    tmpName = m_wsIdentifier;
  }

  js << L"var " << tmpName << L" = null;\n";
  js << L"var pfm_ary = pfm_rt.concat_obj(";
  for (const auto& expr : m_pAccessors) {
    if (!expr->ToJavaScript(js, ReturnType::kInfered))
      return false;
    if (expr != m_pAccessors.back())
      js << L", ";
  }
  js << L");\n";

  js << L"var pfm_ary_idx = 0;\n";
  js << L"while(pfm_ary_idx < pfm_ary.length)\n{\n";
  js << tmpName << L" = pfm_ary[pfm_ary_idx++];\n";
  if (!m_pList->ToJavaScript(js, type))
    return false;
  js << L"}\n";  // while

  js << L"}\n";  // block
  return !CXFA_IsTooBig(js);
}
