// Copyright 2016 PDFium Authors. All rights reserved.
// 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_CFX_STRING_C_TEMPLATE_H_
#define CORE_FXCRT_CFX_STRING_C_TEMPLATE_H_

#include <algorithm>
#include <type_traits>
#include <vector>

#include "core/fxcrt/cfx_unowned_ptr.h"
#include "core/fxcrt/fx_system.h"
#include "third_party/base/stl_util.h"

// 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 Mid(), Left(), and Right() methods) is copy-free.
template <typename T>
class CFX_StringCTemplate {
 public:
  using CharType = T;
  using UnsignedType = typename std::make_unsigned<CharType>::type;
  using const_iterator = const CharType*;

  CFX_StringCTemplate() : m_Ptr(nullptr), m_Length(0) {}

  // Deliberately implicit to avoid calling on every string literal.
  // NOLINTNEXTLINE(runtime/explicit)
  CFX_StringCTemplate(const CharType* ptr)
      : m_Ptr(reinterpret_cast<const UnsignedType*>(ptr)),
        m_Length(ptr ? FXSYS_len(ptr) : 0) {}

  CFX_StringCTemplate(const CharType* ptr, FX_STRSIZE len)
      : m_Ptr(reinterpret_cast<const UnsignedType*>(ptr)),
        m_Length(len == -1 ? FXSYS_len(ptr) : len) {}

  template <typename U = UnsignedType>
  CFX_StringCTemplate(
      const UnsignedType* ptr,
      FX_STRSIZE size,
      typename std::enable_if<!std::is_same<U, CharType>::value>::type* = 0)
      : m_Ptr(ptr), m_Length(size) {}

  // Deliberately implicit to avoid calling on every string literal.
  // |ch| must be an lvalue that outlives the the CFX_StringCTemplate.
  // NOLINTNEXTLINE(runtime/explicit)
  CFX_StringCTemplate(CharType& ch) {
    m_Ptr = reinterpret_cast<const UnsignedType*>(&ch);
    m_Length = 1;
  }

  CFX_StringCTemplate(const CFX_StringCTemplate& src) {
    m_Ptr = src.m_Ptr;
    m_Length = src.m_Length;
  }

  // Any changes to |vec| invalidate the string.
  explicit CFX_StringCTemplate(const std::vector<UnsignedType>& vec) {
    m_Length = pdfium::CollectionSize<FX_STRSIZE>(vec);
    m_Ptr = m_Length ? vec.data() : nullptr;
  }

  CFX_StringCTemplate& operator=(const CharType* src) {
    m_Ptr = reinterpret_cast<const UnsignedType*>(src);
    m_Length = src ? FXSYS_len(src) : 0;
    return *this;
  }

  CFX_StringCTemplate& operator=(const CFX_StringCTemplate& src) {
    m_Ptr = src.m_Ptr;
    m_Length = src.m_Length;
    return *this;
  }

  const_iterator begin() const {
    return reinterpret_cast<const CharType*>(m_Ptr.Get());
  }
  const_iterator end() const {
    return m_Ptr ? reinterpret_cast<const CharType*>(m_Ptr.Get()) + m_Length
                 : nullptr;
  }

  bool operator==(const CharType* ptr) const {
    return FXSYS_len(ptr) == m_Length &&
           FXSYS_cmp(ptr, reinterpret_cast<const CharType*>(m_Ptr.Get()),
                     m_Length) == 0;
  }
  bool operator==(const CFX_StringCTemplate& other) const {
    return other.m_Length == m_Length &&
           FXSYS_cmp(reinterpret_cast<const CharType*>(other.m_Ptr.Get()),
                     reinterpret_cast<const CharType*>(m_Ptr.Get()),
                     m_Length) == 0;
  }
  bool operator!=(const CharType* ptr) const { return !(*this == ptr); }
  bool operator!=(const CFX_StringCTemplate& other) const {
    return !(*this == other);
  }

  uint32_t GetID(FX_STRSIZE start_pos = 0) const {
    if (m_Length == 0 || start_pos < 0 || start_pos >= m_Length)
      return 0;

    uint32_t strid = 0;
    FX_STRSIZE size = std::min(4, m_Length - start_pos);
    for (FX_STRSIZE i = 0; i < size; i++)
      strid = strid * 256 + m_Ptr.Get()[start_pos + i];

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

  const UnsignedType* raw_str() const { return m_Ptr.Get(); }
  const CharType* unterminated_c_str() const {
    return reinterpret_cast<const CharType*>(m_Ptr.Get());
  }

  FX_STRSIZE GetLength() const { return m_Length; }
  bool IsEmpty() const { return m_Length == 0; }

  UnsignedType GetAt(FX_STRSIZE index) const { return m_Ptr.Get()[index]; }
  CharType CharAt(FX_STRSIZE index) const {
    return static_cast<CharType>(m_Ptr.Get()[index]);
  }

  FX_STRSIZE Find(CharType ch) const {
    const UnsignedType* found = reinterpret_cast<const UnsignedType*>(FXSYS_chr(
        reinterpret_cast<const CharType*>(m_Ptr.Get()), ch, m_Length));
    return found ? found - m_Ptr.Get() : -1;
  }

  CFX_StringCTemplate Mid(FX_STRSIZE index, FX_STRSIZE count = -1) const {
    index = std::max(0, index);
    if (index > m_Length)
      return CFX_StringCTemplate();

    if (count < 0 || count > m_Length - index)
      count = m_Length - index;

    return CFX_StringCTemplate(m_Ptr.Get() + index, count);
  }

  CFX_StringCTemplate Left(FX_STRSIZE count) const {
    if (count <= 0)
      return CFX_StringCTemplate();

    return CFX_StringCTemplate(m_Ptr.Get(), std::min(count, m_Length));
  }

  CFX_StringCTemplate Right(FX_STRSIZE count) const {
    if (count <= 0)
      return CFX_StringCTemplate();

    count = std::min(count, m_Length);
    return CFX_StringCTemplate(m_Ptr.Get() + m_Length - count, count);
  }

  const UnsignedType& operator[](size_t index) const {
    return m_Ptr.Get()[index];
  }

  bool operator<(const CFX_StringCTemplate& that) const {
    int result = FXSYS_cmp(reinterpret_cast<const CharType*>(m_Ptr.Get()),
                           reinterpret_cast<const CharType*>(that.m_Ptr.Get()),
                           std::min(m_Length, that.m_Length));
    return result < 0 || (result == 0 && m_Length < that.m_Length);
  }

  bool operator>(const CFX_StringCTemplate& that) const {
    int result = FXSYS_cmp(reinterpret_cast<const CharType*>(m_Ptr.Get()),
                           reinterpret_cast<const CharType*>(that.m_Ptr.Get()),
                           std::min(m_Length, that.m_Length));
    return result > 0 || (result == 0 && m_Length > that.m_Length);
  }

 protected:
  CFX_UnownedPtr<const UnsignedType> m_Ptr;
  FX_STRSIZE m_Length;

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

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

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

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

using CFX_ByteStringC = CFX_StringCTemplate<char>;
using CFX_WideStringC = CFX_StringCTemplate<wchar_t>;

#endif  // CORE_FXCRT_CFX_STRING_C_TEMPLATE_H_
