// 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 "../../include/javascript/IJavaScript.h"
#include "../../include/javascript/JS_Define.h"
#include "../../include/javascript/JS_Object.h"
#include "../../include/javascript/JS_Value.h"
#include "../../include/javascript/util.h"
#include "../../include/javascript/PublicMethods.h"
#include "../../include/javascript/resource.h"
#include "../../include/javascript/JS_Context.h"
#include "../../include/javascript/JS_EventHandler.h"
#include "../../include/javascript/JS_Runtime.h"

#if _FX_OS_ == _FX_ANDROID_
#include <ctype.h>
#endif

static v8::Isolate* GetIsolate(IFXJS_Context* cc) {
  CJS_Context* pContext = (CJS_Context*)cc;
  ASSERT(pContext != NULL);

  CJS_Runtime* pRuntime = pContext->GetJSRuntime();
  ASSERT(pRuntime != NULL);

  return pRuntime->GetIsolate();
}

BEGIN_JS_STATIC_CONST(CJS_Util)
END_JS_STATIC_CONST()

BEGIN_JS_STATIC_PROP(CJS_Util)
END_JS_STATIC_PROP()

BEGIN_JS_STATIC_METHOD(CJS_Util)
JS_STATIC_METHOD_ENTRY(printd)
JS_STATIC_METHOD_ENTRY(printf)
JS_STATIC_METHOD_ENTRY(printx)
JS_STATIC_METHOD_ENTRY(scand)
JS_STATIC_METHOD_ENTRY(byteToChar)
END_JS_STATIC_METHOD()

IMPLEMENT_JS_CLASS(CJS_Util, util)

util::util(CJS_Object* pJSObject) : CJS_EmbedObj(pJSObject) {}

util::~util() {
}

struct stru_TbConvert {
  const FX_WCHAR* lpszJSMark;
  const FX_WCHAR* lpszCppMark;
};

const stru_TbConvert fcTable[] = {
    {L"mmmm", L"%B"},
    {L"mmm", L"%b"},
    {L"mm", L"%m"},
    //"m"
    {L"dddd", L"%A"},
    {L"ddd", L"%a"},
    {L"dd", L"%d"},
    //"d",   "%w",
    {L"yyyy", L"%Y"},
    {L"yy", L"%y"},
    {L"HH", L"%H"},
    //"H"
    {L"hh", L"%I"},
    //"h"
    {L"MM", L"%M"},
    //"M"
    {L"ss", L"%S"},
    //"s
    {L"TT", L"%p"},
//"t"
#if defined(_WIN32)
    {L"tt", L"%p"},
    {L"h", L"%#I"},
#else
    {L"tt", L"%P"},
    {L"h", L"%l"},
#endif
};

#define UTIL_INT 0
#define UTIL_DOUBLE 1
#define UTIL_STRING 2

int util::ParstDataType(std::wstring* sFormat) {
  bool bPercent = FALSE;
  for (size_t i = 0; i < sFormat->length(); ++i) {
    wchar_t c = (*sFormat)[i];
    if (c == L'%') {
      bPercent = true;
      continue;
    }

    if (bPercent) {
      if (c == L'c' || c == L'C' || c == L'd' || c == L'i' || c == L'o' ||
          c == L'u' || c == L'x' || c == L'X') {
        return UTIL_INT;
      }
      if (c == L'e' || c == L'E' || c == L'f' || c == L'g' || c == L'G') {
        return UTIL_DOUBLE;
      }
      if (c == L's' || c == L'S') {
        // Map s to S since we always deal internally
        // with wchar_t strings.
        (*sFormat)[i] = L'S';
        return UTIL_STRING;
      }
      if (c == L'.' || c == L'+' || c == L'-' || c == L'#' || c == L' ' ||
          CJS_PublicMethods::IsDigit(c)) {
        continue;
      }
      break;
    }
  }

  return -1;
}

FX_BOOL util::printf(IFXJS_Context* cc,
                     const CJS_Parameters& params,
                     CJS_Value& vRet,
                     CFX_WideString& sError) {
  int iSize = params.size();
  if (iSize < 1)
    return FALSE;
  std::wstring c_ConvChar(params[0].ToCFXWideString().c_str());
  std::vector<std::wstring> c_strConvers;
  int iOffset = 0;
  int iOffend = 0;
  c_ConvChar.insert(c_ConvChar.begin(), L'S');
  while (iOffset != -1) {
    iOffend = c_ConvChar.find(L"%", iOffset + 1);
    std::wstring strSub;
    if (iOffend == -1)
      strSub = c_ConvChar.substr(iOffset);
    else
      strSub = c_ConvChar.substr(iOffset, iOffend - iOffset);
    c_strConvers.push_back(strSub);
    iOffset = iOffend;
  }

  std::wstring c_strResult;

  // for(int iIndex = 1;iIndex < params.size();iIndex++)
  std::wstring c_strFormat;
  for (int iIndex = 0; iIndex < (int)c_strConvers.size(); iIndex++) {
    c_strFormat = c_strConvers[iIndex];
    if (iIndex == 0) {
      c_strResult = c_strFormat;
      continue;
    }

    CFX_WideString strSegment;
    if (iIndex >= iSize) {
      c_strResult += c_strFormat;
      continue;
    }

    switch (ParstDataType(&c_strFormat)) {
      case UTIL_INT:
        strSegment.Format(c_strFormat.c_str(), params[iIndex].ToInt());
        break;
      case UTIL_DOUBLE:
        strSegment.Format(c_strFormat.c_str(), params[iIndex].ToDouble());
        break;
      case UTIL_STRING:
        strSegment.Format(c_strFormat.c_str(),
                          params[iIndex].ToCFXWideString().c_str());
        break;
      default:
        strSegment.Format(L"%S", c_strFormat.c_str());
        break;
    }
    c_strResult += strSegment.GetBuffer(strSegment.GetLength() + 1);
  }

  c_strResult.erase(c_strResult.begin());
  vRet = c_strResult.c_str();
  return TRUE;
}

FX_BOOL util::printd(IFXJS_Context* cc,
                     const CJS_Parameters& params,
                     CJS_Value& vRet,
                     CFX_WideString& sError) {
  v8::Isolate* isolate = GetIsolate(cc);

  int iSize = params.size();
  if (iSize < 2)
    return FALSE;

  CJS_Value p1(isolate);
  p1 = params[0];

  CJS_Value p2 = params[1];
  CJS_Date jsDate(isolate);
  if (!p2.ConvertToDate(jsDate)) {
    sError = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSPRINT1);
    return FALSE;
  }

  if (!jsDate.IsValidDate()) {
    sError = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSPRINT2);
    return FALSE;
  }

  if (p1.GetType() == CJS_Value::VT_number) {
    int nFormat = p1.ToInt();
    CFX_WideString swResult;

    switch (nFormat) {
      case 0:
        swResult.Format(L"D:%04d%02d%02d%02d%02d%02d", jsDate.GetYear(),
                        jsDate.GetMonth() + 1, jsDate.GetDay(),
                        jsDate.GetHours(), jsDate.GetMinutes(),
                        jsDate.GetSeconds());
        break;
      case 1:
        swResult.Format(L"%04d.%02d.%02d %02d:%02d:%02d", jsDate.GetYear(),
                        jsDate.GetMonth() + 1, jsDate.GetDay(),
                        jsDate.GetHours(), jsDate.GetMinutes(),
                        jsDate.GetSeconds());
        break;
      case 2:
        swResult.Format(L"%04d/%02d/%02d %02d:%02d:%02d", jsDate.GetYear(),
                        jsDate.GetMonth() + 1, jsDate.GetDay(),
                        jsDate.GetHours(), jsDate.GetMinutes(),
                        jsDate.GetSeconds());
        break;
      default:
        return FALSE;
    }

    vRet = swResult.c_str();
    return TRUE;
  }
  if (p1.GetType() == CJS_Value::VT_string) {
    std::basic_string<wchar_t> cFormat = p1.ToCFXWideString().c_str();

    bool bXFAPicture = false;
    if (iSize > 2) {
      bXFAPicture = params[2].ToBool();
    }

    if (bXFAPicture) {
      return FALSE;  // currently, it doesn't support XFAPicture.
    }

    for (size_t i = 0; i < sizeof(fcTable) / sizeof(stru_TbConvert); ++i) {
      int iStart = 0;
      int iEnd;
      while ((iEnd = cFormat.find(fcTable[i].lpszJSMark, iStart)) != -1) {
        cFormat.replace(iEnd, FXSYS_wcslen(fcTable[i].lpszJSMark),
                        fcTable[i].lpszCppMark);
        iStart = iEnd;
      }
    }

    int iYear, iMonth, iDay, iHour, iMin, iSec;
    iYear = jsDate.GetYear();
    iMonth = jsDate.GetMonth();
    iDay = jsDate.GetDay();
    iHour = jsDate.GetHours();
    iMin = jsDate.GetMinutes();
    iSec = jsDate.GetSeconds();

    struct tm time = {};
    time.tm_year = iYear - 1900;
    time.tm_mon = iMonth;
    time.tm_mday = iDay;
    time.tm_hour = iHour;
    time.tm_min = iMin;
    time.tm_sec = iSec;

    struct stru_TbConvertAd {
      const FX_WCHAR* lpszJSMark;
      int iValue;
    };

    stru_TbConvertAd cTableAd[] = {
        {L"m", iMonth + 1}, {L"d", iDay},
        {L"H", iHour},      {L"h", iHour > 12 ? iHour - 12 : iHour},
        {L"M", iMin},       {L"s", iSec},
    };

    for (size_t i = 0; i < sizeof(cTableAd) / sizeof(stru_TbConvertAd); ++i) {
      wchar_t tszValue[10];
      CFX_WideString sValue;
      sValue.Format(L"%d", cTableAd[i].iValue);
      memcpy(tszValue, (wchar_t*)sValue.GetBuffer(sValue.GetLength() + 1),
             (sValue.GetLength() + 1) * sizeof(wchar_t));

      int iStart = 0;
      int iEnd;
      while ((iEnd = cFormat.find(cTableAd[i].lpszJSMark, iStart)) != -1) {
        if (iEnd > 0) {
          if (cFormat[iEnd - 1] == L'%') {
            iStart = iEnd + 1;
            continue;
          }
        }
        cFormat.replace(iEnd, FXSYS_wcslen(cTableAd[i].lpszJSMark), tszValue);
        iStart = iEnd;
      }
    }

    CFX_WideString strFormat;
    wchar_t buf[64] = {};
    strFormat = wcsftime(buf, 64, cFormat.c_str(), &time);
    cFormat = buf;
    vRet = cFormat.c_str();
    return TRUE;
  }
  return FALSE;
}

void util::printd(const std::wstring& cFormat2,
                  CJS_Date jsDate,
                  bool bXFAPicture,
                  std::wstring& cPurpose) {
  std::wstring cFormat = cFormat2;

  if (bXFAPicture) {
    return;  // currently, it doesn't support XFAPicture.
  }

  for (size_t i = 0; i < sizeof(fcTable) / sizeof(stru_TbConvert); ++i) {
    int iStart = 0;
    int iEnd;
    while ((iEnd = cFormat.find(fcTable[i].lpszJSMark, iStart)) != -1) {
      cFormat.replace(iEnd, FXSYS_wcslen(fcTable[i].lpszJSMark),
                      fcTable[i].lpszCppMark);
      iStart = iEnd;
    }
  }

  int iYear, iMonth, iDay, iHour, iMin, iSec;
  iYear = jsDate.GetYear();
  iMonth = jsDate.GetMonth();
  iDay = jsDate.GetDay();
  iHour = jsDate.GetHours();
  iMin = jsDate.GetMinutes();
  iSec = jsDate.GetSeconds();

  struct tm time = {};
  time.tm_year = iYear - 1900;
  time.tm_mon = iMonth;
  time.tm_mday = iDay;
  time.tm_hour = iHour;
  time.tm_min = iMin;
  time.tm_sec = iSec;
  //  COleDateTime cppTm(iYear,iMonth+1,iDay,iHour,iMin,iSec);
  // CString strFormat = cppTm.Format(cFormat.c_str());

  struct stru_TbConvertAd {
    const FX_WCHAR* lpszJSMark;
    int iValue;
  };

  stru_TbConvertAd cTableAd[] = {
      {L"m", iMonth + 1}, {L"d", iDay},
      {L"H", iHour},      {L"h", iHour > 12 ? iHour - 12 : iHour},
      {L"M", iMin},       {L"s", iSec},
  };

  // cFormat = strFormat.GetBuffer(strFormat.GetLength()+1);
  for (size_t i = 0; i < sizeof(cTableAd) / sizeof(stru_TbConvertAd); ++i) {
    wchar_t tszValue[10];
    CFX_WideString sValue;
    sValue.Format(L"%d", cTableAd[i].iValue);
    memcpy(tszValue, (wchar_t*)sValue.GetBuffer(sValue.GetLength() + 1),
           sValue.GetLength() * sizeof(wchar_t));

    int iStart = 0;
    int iEnd;
    while ((iEnd = cFormat.find(cTableAd[i].lpszJSMark, iStart)) != -1) {
      if (iEnd > 0) {
        if (cFormat[iEnd - 1] == L'%') {
          iStart = iEnd + 1;
          continue;
        }
      }
      cFormat.replace(iEnd, FXSYS_wcslen(cTableAd[i].lpszJSMark), tszValue);
      iStart = iEnd;
    }
  }

  CFX_WideString strFormat;
  wchar_t buf[64] = {};
  strFormat = wcsftime(buf, 64, cFormat.c_str(), &time);
  cFormat = buf;
  cPurpose = cFormat;
}

FX_BOOL util::printx(IFXJS_Context* cc,
                     const CJS_Parameters& params,
                     CJS_Value& vRet,
                     CFX_WideString& sError) {
  int iSize = params.size();
  if (iSize < 2)
    return FALSE;
  CFX_WideString sFormat = params[0].ToCFXWideString();
  CFX_WideString sSource = params[1].ToCFXWideString();
  std::string cFormat = CFX_ByteString::FromUnicode(sFormat).c_str();
  std::string cSource = CFX_ByteString::FromUnicode(sSource).c_str();
  std::string cDest;
  printx(cFormat, cSource, cDest);
  vRet = cDest.c_str();
  return TRUE;
}

void util::printx(const std::string& cFormat,
                  const std::string& cSource2,
                  std::string& cPurpose) {
  std::string cSource(cSource2);
  if (!cPurpose.empty())
    // cPurpose.clear();
    cPurpose.erase();
  int itSource = 0;
  int iSize = cSource.size();
  for (int iIndex = 0; iIndex < (int)cFormat.size() && itSource < iSize;
       iIndex++) {
    char letter = cFormat[iIndex];
    switch (letter) {
      case '?':
        cPurpose += cSource[itSource];
        itSource++;
        break;
      case 'X': {
        while (itSource < iSize) {
          if ((cSource[itSource] >= '0' && cSource[itSource] <= '9') ||
              (cSource[itSource] >= 'a' && cSource[itSource] <= 'z') ||
              (cSource[itSource] >= 'A' && cSource[itSource] <= 'Z')) {
            cPurpose += cSource[itSource];
            itSource++;
            break;
          }
          itSource++;
        }
        break;
      } break;
      case 'A': {
        while (itSource < iSize) {
          if ((cSource[itSource] >= 'a' && cSource[itSource] <= 'z') ||
              (cSource[itSource] >= 'A' && cSource[itSource] <= 'Z')) {
            cPurpose += cSource[itSource];
            itSource++;
            break;
          }
          itSource++;
        }
        break;
      } break;
      case '9': {
        while (itSource < iSize) {
          if (cSource[itSource] >= '0' && cSource[itSource] <= '9') {
            cPurpose += cSource[itSource];
            itSource++;
            break;
          }
          itSource++;
        }
        break;
      }
      case '*': {
        cPurpose.append(cSource, itSource, iSize - itSource);
        itSource = iSize - 1;
        break;
      }
      case '\\':
        break;
      case '>': {
        for (std::string::iterator it = cSource.begin(); it != cSource.end();
             it++) {
          *it = toupper(*it);
        }
        break;
      }
      case '<': {
        for (std::string::iterator it = cSource.begin(); it != cSource.end();
             it++) {
          *it = tolower(*it);
        }
        break;
      }
      case '=':
        break;
      default:
        cPurpose += letter;
        break;
    }
  }
}

FX_BOOL util::scand(IFXJS_Context* cc,
                    const CJS_Parameters& params,
                    CJS_Value& vRet,
                    CFX_WideString& sError) {
  v8::Isolate* isolate = GetIsolate(cc);
  int iSize = params.size();
  if (iSize < 2)
    return FALSE;

  CFX_WideString sFormat = params[0].ToCFXWideString();
  CFX_WideString sDate = params[1].ToCFXWideString();
  double dDate = JS_GetDateTime();
  if (sDate.GetLength() > 0) {
    FX_BOOL bWrongFormat = FALSE;
    dDate = CJS_PublicMethods::MakeRegularDate(sDate, sFormat, bWrongFormat);
  }

  if (!JS_PortIsNan(dDate)) {
    CJS_Date date(isolate, dDate);
    vRet = date;
  } else {
    vRet.SetNull();
  }

  return TRUE;
}

int64_t FX_atoi64(const char* nptr) {
  int c;         /* current char */
  int64_t total; /* current total */
  int sign;      /* if '-', then negative, otherwise positive */

  /* skip whitespace */
  while (isspace((int)(unsigned char)*nptr))
    ++nptr;

  c = (int)(unsigned char)*nptr++;
  sign = c; /* save sign indication */
  if (c == '-' || c == '+')
    c = (int)(unsigned char)*nptr++; /* skip sign */

  total = 0;

  while (isdigit(c)) {
    total = 10 * total + (c - '0');  /* accumulate digit */
    c = (int)(unsigned char)*nptr++; /* get next char */
  }

  return sign == '-' ? -total : total;
}

FX_BOOL util::byteToChar(IFXJS_Context* cc,
                         const CJS_Parameters& params,
                         CJS_Value& vRet,
                         CFX_WideString& sError) {
  int iSize = params.size();
  if (iSize == 0)
    return FALSE;
  int nByte = params[0].ToInt();
  unsigned char cByte = (unsigned char)nByte;
  CFX_WideString csValue;
  csValue.Format(L"%c", cByte);
  vRet = csValue.c_str();
  return TRUE;
}
