// Copyright 2016 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

#ifndef CORE_FXCRT_STRING_VIEW_TEMPLATE_H_
#define CORE_FXCRT_STRING_VIEW_TEMPLATE_H_

#include <ctype.h>

#include <algorithm>
#include <iterator>
#include <optional>
#include <string>
#include <type_traits>

#include "core/fxcrt/compiler_specific.h"
#include "core/fxcrt/fx_memcpy_wrappers.h"
#include "core/fxcrt/fx_system.h"
#include "core/fxcrt/span.h"
#include "core/fxcrt/span_util.h"

namespace fxcrt {

// An immutable string with caller-provided storage which must outlive the
// string itself. These are not necessarily nul-terminated, so that substring
// extraction (via the Substr(), First(), and Last() methods) is copy-free.
//
// String view arguments should be passed by value, since they are small,
// rather than const-ref, even if they are not modified.
//
// Front() and Back() tolerate empty strings and must return NUL in those
// cases. Substr(), First(), and Last() tolerate out-of-range indices and
// must return an empty string view in those cases. The aim here is allowing
// callers to avoid range-checking first.
template <typename T>
class StringViewTemplate {
 public:
  using CharType = T;
  using UnsignedType = typename std::make_unsigned<CharType>::type;
  using const_iterator = const CharType*;
  using const_reverse_iterator = std::reverse_iterator<const_iterator>;

  constexpr StringViewTemplate() noexcept = default;
  constexpr StringViewTemplate(const StringViewTemplate& src) noexcept =
      default;

  // Deliberately implicit to avoid calling on every string literal.
  // NOLINTNEXTLINE(runtime/explicit)
  StringViewTemplate(const CharType* ptr) noexcept
      // SAFETY: from length() function.
      : m_Span(UNSAFE_BUFFERS(pdfium::make_span(
            reinterpret_cast<const UnsignedType*>(ptr),
            ptr ? std::char_traits<CharType>::length(ptr) : 0))) {}

  UNSAFE_BUFFER_USAGE
  constexpr StringViewTemplate(const CharType* ptr, size_t size) noexcept
      // SAFETY: propagated to caller via UNSAFE_BUFFER_USAGE.
      : m_Span(UNSAFE_BUFFERS(
            pdfium::make_span(reinterpret_cast<const UnsignedType*>(ptr),
                              size))) {}

  template <typename E = typename std::enable_if<
                !std::is_same<UnsignedType, CharType>::value>::type>
  UNSAFE_BUFFER_USAGE constexpr StringViewTemplate(const UnsignedType* ptr,
                                                   size_t size) noexcept
      // SAFETY: propagated to caller via UNSAFE_BUFFER_USAGE.
      : m_Span(UNSAFE_BUFFERS(pdfium::make_span(ptr, size))) {}

  explicit constexpr StringViewTemplate(
      const pdfium::span<const CharType>& other) noexcept {
    if (!other.empty()) {
      m_Span = reinterpret_span<const UnsignedType>(other);
    }
  }

  template <typename E = typename std::enable_if<
                !std::is_same<UnsignedType, CharType>::value>::type>
  constexpr StringViewTemplate(
      const pdfium::span<const UnsignedType>& other) noexcept {
    if (!other.empty()) {
      m_Span = other;
    }
  }

  // Deliberately implicit to avoid calling on every char literal.
  // |ch| must be an lvalue that outlives the StringViewTemplate.
  // NOLINTNEXTLINE(runtime/explicit)
  constexpr StringViewTemplate(const CharType& ch) noexcept
      : m_Span(
            reinterpret_span<const UnsignedType>(pdfium::span_from_ref(ch))) {}

  StringViewTemplate& operator=(const CharType* src) {
    // SAFETY: caller ensures `src` is nul-terminated so `length()` is correct.
    m_Span = UNSAFE_BUFFERS(
        pdfium::make_span(reinterpret_cast<const UnsignedType*>(src),
                          src ? std::char_traits<CharType>::length(src) : 0));
    return *this;
  }

  StringViewTemplate& operator=(const StringViewTemplate& src) {
    m_Span = src.m_Span;
    return *this;
  }

  const_iterator begin() const {
    return reinterpret_cast<const_iterator>(m_Span.begin());
  }
  const_iterator end() const {
    return reinterpret_cast<const_iterator>(m_Span.end());
  }
  const_reverse_iterator rbegin() const {
    return const_reverse_iterator(end());
  }
  const_reverse_iterator rend() const {
    return const_reverse_iterator(begin());
  }

  bool operator==(const StringViewTemplate& other) const {
    return std::equal(m_Span.begin(), m_Span.end(), other.m_Span.begin(),
                      other.m_Span.end());
  }
  bool operator==(const CharType* ptr) const {
    StringViewTemplate other(ptr);
    return *this == other;
  }
  bool operator!=(const CharType* ptr) const { return !(*this == ptr); }
  bool operator!=(const StringViewTemplate& other) const {
    return !(*this == other);
  }

  bool IsASCII() const {
    for (auto c : *this) {
      if (c <= 0 || c > 127)  // Questionable signedness of |c|.
        return false;
    }
    return true;
  }

  bool EqualsASCII(const StringViewTemplate<char>& that) const {
    size_t length = GetLength();
    if (length != that.GetLength())
      return false;

    for (size_t i = 0; i < length; ++i) {
      auto c = (*this)[i];
      if (c <= 0 || c > 127 || c != that[i])  // Questionable signedness of |c|.
        return false;
    }
    return true;
  }

  bool EqualsASCIINoCase(const StringViewTemplate<char>& that) const {
    size_t length = GetLength();
    if (length != that.GetLength())
      return false;

    for (size_t i = 0; i < length; ++i) {
      auto c = (*this)[i];
      if (c <= 0 || c > 127 || tolower(c) != tolower(that[i]))
        return false;
    }
    return true;
  }

  uint32_t GetID() const {
    if (m_Span.empty())
      return 0;

    uint32_t strid = 0;
    size_t size = std::min(static_cast<size_t>(4), m_Span.size());
    for (size_t i = 0; i < size; i++)
      strid = strid * 256 + m_Span[i];

    return strid << ((4 - size) * 8);
  }

  pdfium::span<const UnsignedType> unsigned_span() const { return m_Span; }
  pdfium::span<const CharType> span() const {
    return reinterpret_span<const CharType>(m_Span);
  }
  const UnsignedType* unterminated_unsigned_str() const {
    return m_Span.data();
  }
  const CharType* unterminated_c_str() const {
    return reinterpret_cast<const CharType*>(m_Span.data());
  }

  size_t GetLength() const { return m_Span.size(); }
  bool IsEmpty() const { return m_Span.empty(); }
  bool IsValidIndex(size_t index) const { return index < m_Span.size(); }
  bool IsValidLength(size_t length) const { return length <= m_Span.size(); }

  // CHECK() if index is out of range (via span's operator[]).
  const UnsignedType& operator[](const size_t index) const {
    return m_Span[index];
  }

  // CHECK() if index is out of range (via span's operator[]).
  CharType CharAt(const size_t index) const {
    return static_cast<CharType>(m_Span[index]);
  }

  // Unlike std::string_view::front(), this is always safe and returns a
  // NUL char when the string is empty.
  UnsignedType Front() const { return !m_Span.empty() ? m_Span.front() : 0; }

  // Unlike std::string_view::back(), this is always safe and returns a
  // NUL char when the string is empty.
  UnsignedType Back() const { return !m_Span.empty() ? m_Span.back() : 0; }

  std::optional<size_t> Find(CharType ch) const {
    const auto* found =
        reinterpret_cast<const UnsignedType*>(std::char_traits<CharType>::find(
            reinterpret_cast<const CharType*>(m_Span.data()), m_Span.size(),
            ch));

    return found ? std::optional<size_t>(found - m_Span.data()) : std::nullopt;
  }

  bool Contains(CharType ch) const { return Find(ch).has_value(); }

  StringViewTemplate Substr(size_t offset) const {
    // Unsigned underflow is well-defined and out-of-range is handled by
    // Substr().
    return Substr(offset, GetLength() - offset);
  }

  StringViewTemplate Substr(size_t first, size_t count) const {
    if (!m_Span.data())
      return StringViewTemplate();

    if (!IsValidIndex(first))
      return StringViewTemplate();

    if (count == 0 || !IsValidLength(count))
      return StringViewTemplate();

    if (!IsValidIndex(first + count - 1))
      return StringViewTemplate();

    // SAFETY: performance-sensitive, checks above equivalent to subspan()'s.
    return UNSAFE_BUFFERS(StringViewTemplate(m_Span.data() + first, count));
  }

  StringViewTemplate First(size_t count) const {
    return Substr(0, count);
  }

  StringViewTemplate Last(size_t count) const {
    // Unsigned underflow is well-defined and out-of-range is handled by
    // Substr().
    return Substr(GetLength() - count, count);
  }

  StringViewTemplate TrimmedRight(CharType ch) const {
    if (IsEmpty())
      return StringViewTemplate();

    size_t pos = GetLength();
    while (pos && CharAt(pos - 1) == ch)
      pos--;

    if (pos == 0)
      return StringViewTemplate();

    return StringViewTemplate(m_Span.data(), pos);
  }

  bool operator<(const StringViewTemplate& that) const {
    const size_t common_size = std::min(m_Span.size(), that.m_Span.size());
    int result =
        common_size ? std::char_traits<CharType>::compare(
                          reinterpret_cast<const CharType*>(m_Span.data()),
                          reinterpret_cast<const CharType*>(that.m_Span.data()),
                          common_size)
                    : 0;
    return result < 0 || (result == 0 && m_Span.size() < that.m_Span.size());
  }

  bool operator>(const StringViewTemplate& that) const {
    const size_t common_size = std::min(m_Span.size(), that.m_Span.size());
    int result =
        common_size ? std::char_traits<CharType>::compare(
                          reinterpret_cast<const CharType*>(m_Span.data()),
                          reinterpret_cast<const CharType*>(that.m_Span.data()),
                          common_size)
                    : 0;
    return result > 0 || (result == 0 && m_Span.size() > that.m_Span.size());
  }

 protected:
  // This is not a raw_span<> because StringViewTemplates must be passed by
  // value without introducing BackupRefPtr churn. Also, repeated re-assignment
  // of substrings of a StringViewTemplate to itself must avoid the same issue.
  pdfium::span<const UnsignedType> m_Span;

 private:
  void* operator new(size_t) throw() { return nullptr; }
};

template <typename T>
inline bool operator==(const T* lhs, const StringViewTemplate<T>& rhs) {
  return rhs == lhs;
}
template <typename T>
inline bool operator!=(const T* lhs, const StringViewTemplate<T>& rhs) {
  return rhs != lhs;
}
template <typename T>
inline bool operator<(const T* lhs, const StringViewTemplate<T>& rhs) {
  return rhs > lhs;
}

extern template class StringViewTemplate<char>;
extern template class StringViewTemplate<wchar_t>;

using ByteStringView = StringViewTemplate<char>;
using WideStringView = StringViewTemplate<wchar_t>;

}  // namespace fxcrt

using ByteStringView = fxcrt::ByteStringView;
using WideStringView = fxcrt::WideStringView;

#endif  // CORE_FXCRT_STRING_VIEW_TEMPLATE_H_
