// 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 "core/fxcrt/fx_string.h"

#include <stdint.h>

#include <array>
#include <limits>
#include <string>
#include <vector>

#include "build/build_config.h"
#include "core/fxcrt/bytestring.h"
#include "core/fxcrt/code_point_view.h"
#include "core/fxcrt/fx_extension.h"
#include "core/fxcrt/span.h"
#include "core/fxcrt/utf16.h"
#include "core/fxcrt/widestring.h"
#include "third_party/fast_float/src/include/fast_float/fast_float.h"

#if !defined(WCHAR_T_IS_16_BIT) && !defined(WCHAR_T_IS_32_BIT)
#error "Unknown wchar_t size"
#endif
#if defined(WCHAR_T_IS_16_BIT) && defined(WCHAR_T_IS_32_BIT)
#error "Conflicting wchar_t sizes"
#endif

namespace {

// Appends a Unicode code point to a `ByteString` using UTF-8.
//
// TODO(crbug.com/pdfium/2041): Migrate to `ByteString`.
void AppendCodePointToByteString(char32_t code_point, ByteString& buffer) {
  if (code_point > pdfium::kMaximumSupplementaryCodePoint) {
    // Invalid code point above U+10FFFF.
    return;
  }

  if (code_point < 0x80) {
    // 7-bit code points are unchanged in UTF-8.
    buffer += code_point;
    return;
  }

  int byte_size;
  if (code_point < 0x800) {
    byte_size = 2;
  } else if (code_point < 0x10000) {
    byte_size = 3;
  } else {
    byte_size = 4;
  }

  static constexpr std::array<uint8_t, 3> kPrefix = {{0xc0, 0xe0, 0xf0}};
  int order = 1 << ((byte_size - 1) * 6);
  buffer += kPrefix[byte_size - 2] | (code_point / order);
  for (int i = 0; i < byte_size - 1; i++) {
    code_point = code_point % order;
    order >>= 6;
    buffer += 0x80 | (code_point / order);
  }
}

template <typename IntType, typename StringViewType>
IntType StringToIntImpl(StringViewType str) {
  if (str.IsEmpty()) {
    return 0;
  }

  // Process the sign.
  bool neg = str.CharAt(0u) == '-';
  if (neg || str.CharAt(0u) == '+') {
    str = str.Substr(1u);
  }

  IntType num = 0;
  while (!str.IsEmpty() && FXSYS_IsDecimalDigit(str.CharAt(0u))) {
    IntType val = FXSYS_DecimalCharToInt(str.CharAt(0u));
    if (num > (std::numeric_limits<IntType>::max() - val) / 10) {
      if (neg && std::numeric_limits<IntType>::is_signed) {
        // Return MIN when the represented number is signed type and is smaller
        // than the min value.
        return std::numeric_limits<IntType>::min();
      }
      // Return MAX when the represented number is signed type and is larger
      // than the max value, or the number is unsigned type and out of range.
      return std::numeric_limits<IntType>::max();
    }
    num = num * 10 + val;
    str = str.Substr(1u);
  }
  // When it is a negative value, -num should be returned. Since num may be of
  // unsigned type, use ~num + 1 to avoid the warning of applying unary minus
  // operator to unsigned type.
  return neg ? ~num + 1 : num;
}

// Intended to work for the cases where `T` is float or double.
template <class T>
T StringToFloatImpl(ByteStringView strc) {
  // Skip leading whitespaces.
  size_t start = 0;
  size_t len = strc.GetLength();
  while (start < len && strc[start] == ' ') {
    ++start;
  }

  // Skip a leading '+' sign.
  if (start < len && strc[start] == '+') {
    ++start;
  }

  ByteStringView sub_strc = strc.Substr(start, len - start);

  T value;
  auto result = fast_float::from_chars(sub_strc.begin(), sub_strc.end(), value);

  // Return 0 for parsing errors. Some examples of errors are an empty string
  // and a string that cannot be converted to T.
  return result.ec == std::errc() || result.ec == std::errc::result_out_of_range
             ? value
             : 0;
}

}  // namespace

ByteString FX_UTF8Encode(WideStringView wsStr) {
  ByteString buffer;
  for (char32_t code_point : pdfium::CodePointView(wsStr)) {
    AppendCodePointToByteString(code_point, buffer);
  }
  return buffer;
}

std::u16string FX_UTF16Encode(WideStringView wsStr) {
  if (wsStr.IsEmpty()) {
    return {};
  }

  std::u16string result;
  result.reserve(wsStr.GetLength());

  for (wchar_t c : wsStr) {
#if defined(WCHAR_T_IS_32_BIT)
    if (pdfium::IsSupplementary(c)) {
      pdfium::SurrogatePair pair(c);
      result.push_back(pair.high());
      result.push_back(pair.low());
      continue;
    }
#endif  // defined(WCHAR_T_IS_32_BIT)
    result.push_back(c);
  }

  return result;
}

int32_t StringToInt(ByteStringView str) {
  return StringToIntImpl<int32_t, ByteStringView>(str);
}

int32_t StringToInt(WideStringView wsStr) {
  return StringToIntImpl<int32_t, WideStringView>(wsStr);
}

float StringToFloat(ByteStringView strc) {
  return StringToFloatImpl<float>(strc);
}

float StringToFloat(WideStringView wsStr) {
  return StringToFloat(FX_UTF8Encode(wsStr).AsStringView());
}

double StringToDouble(ByteStringView strc) {
  return StringToFloatImpl<double>(strc);
}

double StringToDouble(WideStringView wsStr) {
  return StringToDouble(FX_UTF8Encode(wsStr).AsStringView());
}

namespace fxcrt {

template std::vector<ByteString> Split<ByteString>(const ByteString& that,
                                                   ByteString::CharType ch);
template std::vector<WideString> Split<WideString>(const WideString& that,
                                                   WideString::CharType ch);

}  // namespace fxcrt
