// Copyright 2009 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/strings/utf_string_conversion_utils.h"

#include <string>
#include <string_view>

#include "base/containers/span.h"
#include "base/third_party/icu/icu_utf.h"
#include "build/build_config.h"

namespace base {

// CountUnicodeCharacters ------------------------------------------------------

std::optional<size_t> CountUnicodeCharacters(std::string_view text,
                                             size_t limit) {
  base_icu::UChar32 unused = 0;
  size_t count = 0;
  for (size_t index = 0; count < limit && index < text.size();
       ++count, ++index) {
    if (!ReadUnicodeCharacter(text, &index, &unused)) {
      return std::nullopt;
    }
  }
  return count;
}

// ReadUnicodeCharacter --------------------------------------------------------

bool ReadUnicodeCharacter(std::string_view src,
                          size_t* char_index,
                          base_icu::UChar32* code_point_out) {
  if (*char_index >= src.size()) {
    return false;
  }
  base_icu::UChar32 code_point;
  UNSAFE_TODO(CBU8_NEXT(base::as_bytes(base::span(src)), *char_index,
                        src.size(), code_point));
  *code_point_out = code_point;

  // The ICU macro above moves to the next char, we want to point to the last
  // char consumed.
  (*char_index)--;

  // Validate the decoded value.
  return IsValidCodepoint(code_point);
}

bool ReadUnicodeCharacter(const char* src,
                          size_t src_len,
                          size_t* char_index,
                          base_icu::UChar32* code_point_out) {
  return ReadUnicodeCharacter(std::string_view(src, src_len), char_index,
                              code_point_out);
}

bool ReadUnicodeCharacter(std::u16string_view src,
                          size_t* char_index,
                          base_icu::UChar32* code_point) {
  if (*char_index >= src.size()) {
    return false;
  }

  if (CBU16_IS_SURROGATE(src[*char_index])) {
    if (!CBU16_IS_SURROGATE_LEAD(src[*char_index]) ||
        *char_index >= src.size() - 1 ||
        !CBU16_IS_TRAIL(src[*char_index + 1])) {
      // Invalid surrogate pair.
      return false;
    }

    // Valid surrogate pair.
    *code_point =
        CBU16_GET_SUPPLEMENTARY(src[*char_index], src[*char_index + 1]);
    (*char_index)++;
  } else {
    // Not a surrogate, just one 16-bit word.
    *code_point = src[*char_index];
  }

  return IsValidCodepoint(*code_point);
}

bool ReadUnicodeCharacter(const char16_t* src,
                          size_t src_len,
                          size_t* char_index,
                          base_icu::UChar32* code_point) {
  return ReadUnicodeCharacter(std::u16string_view(src, src_len), char_index,
                              code_point);
}

#if defined(WCHAR_T_IS_32_BIT)
bool ReadUnicodeCharacter(std::wstring_view src,
                          size_t* char_index,
                          base_icu::UChar32* code_point) {
  if (*char_index >= src.size()) {
    return false;
  }

  // Conversion is easy since the source is 32-bit.
  *code_point = static_cast<base_icu::UChar32>(src[*char_index]);

  // Validate the value.
  return IsValidCodepoint(*code_point);
}

bool ReadUnicodeCharacter(const wchar_t* src,
                          size_t src_len,
                          size_t* char_index,
                          base_icu::UChar32* code_point) {
  return ReadUnicodeCharacter(std::wstring_view(src, src_len), char_index,
                              code_point);
}
#endif  // defined(WCHAR_T_IS_32_BIT)

// WriteUnicodeCharacter -------------------------------------------------------

size_t WriteUnicodeCharacter(base_icu::UChar32 code_point,
                             std::string* output) {
  if (code_point >= 0 && code_point <= 0x7f) {
    // Fast path the common case of one byte.
    output->push_back(static_cast<char>(code_point));
    return 1;
  }

  // CBU8_APPEND_UNSAFE can append up to 4 bytes.
  size_t char_offset = output->length();
  size_t original_char_offset = char_offset;
  output->resize(char_offset + CBU8_MAX_LENGTH);

  UNSAFE_TODO(CBU8_APPEND_UNSAFE(reinterpret_cast<uint8_t*>(output->data()),
                                 char_offset, code_point));

  // CBU8_APPEND_UNSAFE will advance our pointer past the inserted character, so
  // it will represent the new length of the string.
  output->resize(char_offset);
  return char_offset - original_char_offset;
}

size_t WriteUnicodeCharacter(base_icu::UChar32 code_point,
                             std::u16string* output) {
  if (CBU16_LENGTH(code_point) == 1) {
    // The code point is in the Basic Multilingual Plane (BMP).
    output->push_back(static_cast<char16_t>(code_point));
    return 1;
  }
  // Non-BMP characters use a double-character encoding.
  size_t char_offset = output->length();
  output->resize(char_offset + CBU16_MAX_LENGTH);
  UNSAFE_TODO(CBU16_APPEND_UNSAFE(&(*output)[0], char_offset, code_point));
  return CBU16_MAX_LENGTH;
}

// Generalized Unicode converter -----------------------------------------------

template <typename CHAR>
void PrepareForUTF8Output(std::basic_string_view<CHAR> src,
                          std::string* output) {
  output->clear();
  if (src.empty()) {
    return;
  }
  if (src[0] < 0x80) {
    // Assume that the entire input will be ASCII.
    output->reserve(src.size());
  } else {
    // Assume that the entire input is non-ASCII and will have 3 bytes per char.
    output->reserve(src.size() * 3);
  }
}

// Instantiate versions we know callers will need.
#if !BUILDFLAG(IS_WIN)
// wchar_t and char16_t are the same thing on Windows.
template void PrepareForUTF8Output(std::wstring_view, std::string*);
#endif
template void PrepareForUTF8Output(std::u16string_view, std::string*);

template <typename STRING>
void PrepareForUTF16Or32Output(std::string_view src, STRING* output) {
  output->clear();
  if (src.empty()) {
    return;
  }
  if (static_cast<unsigned char>(src[0]) < 0x80) {
    // Assume the input is all ASCII, which means 1:1 correspondence.
    output->reserve(src.size());
  } else {
    // Otherwise assume that the UTF-8 sequences will have 2 bytes for each
    // character.
    output->reserve(src.size() / 2);
  }
}

// Instantiate versions we know callers will need.
#if !BUILDFLAG(IS_WIN)
// std::wstring and std::u16string are the same thing on Windows.
template void PrepareForUTF16Or32Output(std::string_view, std::wstring*);
#endif
template void PrepareForUTF16Or32Output(std::string_view, std::u16string*);

}  // namespace base
