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

#include "../../include/javascript/IJavaScript.h"
#include "JS_Context.h"
#include "JS_Define.h"
#include "JS_EventHandler.h"
#include "JS_Object.h"
#include "JS_Runtime.h"
#include "JS_Value.h"
#include "PublicMethods.h"
#include "resource.h"

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

static v8::Isolate* GetIsolate(IJS_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(IJS_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(IJS_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(IJS_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(IJS_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(IJS_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;
}
