// 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 <type_traits>

#include "core/fxcrt/fx_memcpy_wrappers.h"
#include "core/fxcrt/fx_system.h"
#include "core/fxcrt/span.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
      : m_Span(reinterpret_cast<const UnsignedType*>(ptr),
               ptr ? FXSYS_len(ptr) : 0) {}

  constexpr StringViewTemplate(const CharType* ptr, size_t size) noexcept
      : m_Span(reinterpret_cast<const UnsignedType*>(ptr), size) {}

  template <typename E = typename std::enable_if<
                !std::is_same<UnsignedType, CharType>::value>::type>
  constexpr StringViewTemplate(const UnsignedType* ptr, size_t size) noexcept
      : m_Span(ptr, size) {}

  explicit constexpr StringViewTemplate(
      const pdfium::span<const CharType>& other) noexcept
      : m_Span(!other.empty()
                   ? reinterpret_cast<const UnsignedType*>(other.data())
                   : nullptr,
               other.size()) {}

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

  // 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_cast<const UnsignedType*>(&ch), 1u) {}

  StringViewTemplate& operator=(const CharType* src) {
    m_Span = pdfium::span<const UnsignedType>(
        reinterpret_cast<const UnsignedType*>(src), src ? FXSYS_len(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 pdfium::make_span(reinterpret_cast<const CharType*>(m_Span.data()),
                             m_Span.size());
  }
  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*>(FXSYS_chr(
        reinterpret_cast<const CharType*>(m_Span.data()), ch, m_Span.size()));

    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();

    return StringViewTemplate(m_Span.subspan(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 {
    int result =
        FXSYS_cmp(reinterpret_cast<const CharType*>(m_Span.data()),
                  reinterpret_cast<const CharType*>(that.m_Span.data()),
                  std::min(m_Span.size(), that.m_Span.size()));
    return result < 0 || (result == 0 && m_Span.size() < that.m_Span.size());
  }

  bool operator>(const StringViewTemplate& that) const {
    int result =
        FXSYS_cmp(reinterpret_cast<const CharType*>(m_Span.data()),
                  reinterpret_cast<const CharType*>(that.m_Span.data()),
                  std::min(m_Span.size(), that.m_Span.size()));
    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_
