// Copyright 2014 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 "core/fxcrt/fx_extension.h"

#include <algorithm>
#include <limits>

#include "core/fxcrt/fx_system.h"
#include "core/fxcrt/utf16.h"
#include "third_party/base/check.h"

namespace {

time_t DefaultTimeFunction() {
  return time(nullptr);
}

struct tm* DefaultLocaltimeFunction(const time_t* tp) {
  return localtime(tp);
}

time_t (*g_time_func)() = DefaultTimeFunction;
struct tm* (*g_localtime_func)(const time_t*) = DefaultLocaltimeFunction;

}  // namespace

float FXSYS_wcstof(const wchar_t* pwsStr, size_t nLength, size_t* pUsedLen) {
  DCHECK(pwsStr);
  if (nLength == 0)
    return 0.0f;

  size_t nUsedLen = 0;
  bool bNegtive = false;
  switch (pwsStr[nUsedLen]) {
    case '-':
      bNegtive = true;
      [[fallthrough]];
    case '+':
      nUsedLen++;
      break;
  }

  float fValue = 0.0f;
  while (nUsedLen < nLength) {
    wchar_t wch = pwsStr[nUsedLen];
    if (!FXSYS_IsDecimalDigit(wch))
      break;

    fValue = fValue * 10.0f + (wch - L'0');
    nUsedLen++;
  }

  if (nUsedLen < nLength && pwsStr[nUsedLen] == L'.') {
    float fPrecise = 0.1f;
    while (++nUsedLen < nLength) {
      wchar_t wch = pwsStr[nUsedLen];
      if (!FXSYS_IsDecimalDigit(wch))
        break;

      fValue += (wch - L'0') * fPrecise;
      fPrecise *= 0.1f;
    }
  }

  if (nUsedLen < nLength &&
      (pwsStr[nUsedLen] == 'e' || pwsStr[nUsedLen] == 'E')) {
    ++nUsedLen;

    bool negative_exponent = false;
    if (nUsedLen < nLength &&
        (pwsStr[nUsedLen] == '-' || pwsStr[nUsedLen] == '+')) {
      negative_exponent = pwsStr[nUsedLen] == '-';
      ++nUsedLen;
    }

    int32_t exp_value = 0;
    while (nUsedLen < nLength) {
      wchar_t wch = pwsStr[nUsedLen];
      if (!FXSYS_IsDecimalDigit(wch))
        break;

      exp_value = exp_value * 10.0f + (wch - L'0');
      // Exponent is outside the valid range, fail.
      if ((negative_exponent &&
           -exp_value < std::numeric_limits<float>::min_exponent10) ||
          (!negative_exponent &&
           exp_value > std::numeric_limits<float>::max_exponent10)) {
        if (pUsedLen)
          *pUsedLen = 0;
        return 0.0f;
      }

      ++nUsedLen;
    }

    for (size_t i = exp_value; i > 0; --i) {
      if (exp_value > 0) {
        if (negative_exponent)
          fValue /= 10;
        else
          fValue *= 10;
      }
    }
  }

  if (pUsedLen)
    *pUsedLen = nUsedLen;

  return bNegtive ? -fValue : fValue;
}

wchar_t* FXSYS_wcsncpy(wchar_t* dstStr, const wchar_t* srcStr, size_t count) {
  DCHECK(dstStr);
  DCHECK(srcStr);
  DCHECK(count > 0);

  for (size_t i = 0; i < count; ++i)
    if ((dstStr[i] = srcStr[i]) == L'\0')
      break;
  return dstStr;
}

int32_t FXSYS_wcsnicmp(const wchar_t* s1, const wchar_t* s2, size_t count) {
  DCHECK(s1);
  DCHECK(s2);
  DCHECK(count > 0);

  while (count-- > 0) {
    wchar_t wch1 = static_cast<wchar_t>(FXSYS_towlower(*s1++));
    wchar_t wch2 = static_cast<wchar_t>(FXSYS_towlower(*s2++));
    if (wch1 != wch2) {
      return wch1 > wch2 ? 1 : -1;
    }
  }
  return 0;
}

void FXSYS_IntToTwoHexChars(uint8_t n, char* buf) {
  static const char kHex[] = "0123456789ABCDEF";
  buf[0] = kHex[n / 16];
  buf[1] = kHex[n % 16];
}

void FXSYS_IntToFourHexChars(uint16_t n, char* buf) {
  FXSYS_IntToTwoHexChars(n / 256, buf);
  FXSYS_IntToTwoHexChars(n % 256, buf + 2);
}

size_t FXSYS_ToUTF16BE(uint32_t unicode, char* buf) {
  DCHECK(unicode <= pdfium::kMaximumSupplementaryCodePoint);
  DCHECK(!pdfium::IsHighSurrogate(unicode));
  DCHECK(!pdfium::IsLowSurrogate(unicode));

  if (unicode <= 0xFFFF) {
    FXSYS_IntToFourHexChars(unicode, buf);
    return 4;
  }
  pdfium::SurrogatePair surrogate_pair(unicode);
  FXSYS_IntToFourHexChars(surrogate_pair.high(), buf);
  FXSYS_IntToFourHexChars(surrogate_pair.low(), buf + 4);
  return 8;
}

void FXSYS_SetTimeFunction(time_t (*func)()) {
  g_time_func = func ? func : DefaultTimeFunction;
}

void FXSYS_SetLocaltimeFunction(struct tm* (*func)(const time_t*)) {
  g_localtime_func = func ? func : DefaultLocaltimeFunction;
}

time_t FXSYS_time(time_t* tloc) {
  time_t ret_val = g_time_func();
  if (tloc)
    *tloc = ret_val;
  return ret_val;
}

struct tm* FXSYS_localtime(const time_t* tp) {
  return g_localtime_func(tp);
}
