// Copyright 2024 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_TEMPLATE_H_
#define CORE_FXCRT_STRING_TEMPLATE_H_

#include <stddef.h>

#include <type_traits>

#include "core/fxcrt/retain_ptr.h"
#include "core/fxcrt/string_data_template.h"
#include "core/fxcrt/string_view_template.h"

namespace fxcrt {

// Base class for a  mutable string with shared buffers using copy-on-write
// semantics that avoids std::string's iterator stability guarantees.
template <typename T>
class StringTemplate {
 public:
  using CharType = T;
  using UnsignedType = typename std::make_unsigned<CharType>::type;
  using StringView = StringViewTemplate<T>;
  using const_iterator = T*;
  using const_reverse_iterator = std::reverse_iterator<const_iterator>;

  bool IsEmpty() const { return !GetLength(); }
  size_t GetLength() const { return m_pData ? m_pData->m_nDataLength : 0; }

  // Explicit conversion to UnsignedType*. May return nullptr.
  // Note: Any subsequent modification of |this| will invalidate the result.
  const UnsignedType* unsigned_str() const {
    return m_pData ? reinterpret_cast<const UnsignedType*>(m_pData->m_String)
                   : nullptr;
  }

  // Explicit conversion to StringView.
  // Note: Any subsequent modification of |this| will invalidate the result.
  StringView AsStringView() const {
    return StringView(unsigned_str(), GetLength());
  }

  // Explicit conversion to span.
  // Note: Any subsequent modification of |this| will invalidate the result.
  pdfium::span<const CharType> span() const {
    return pdfium::make_span(m_pData ? m_pData->m_String : nullptr,
                             GetLength());
  }

  // Explicit conversion to spans of unsigned types.
  // Note: Any subsequent modification of |this| will invalidate the result.
  pdfium::span<const UnsignedType> unsigned_span() const {
    return pdfium::make_span(unsigned_str(), GetLength());
  }

  // Note: Any subsequent modification of |this| will invalidate iterators.
  const_iterator begin() const {
    return m_pData ? m_pData->span().begin() : nullptr;
  }
  const_iterator end() const {
    return m_pData ? m_pData->span().end() : nullptr;
  }

  // Note: Any subsequent modification of |this| will invalidate iterators.
  const_reverse_iterator rbegin() const {
    return const_reverse_iterator(end());
  }
  const_reverse_iterator rend() const {
    return const_reverse_iterator(begin());
  }

  bool IsValidIndex(size_t index) const { return index < GetLength(); }
  bool IsValidLength(size_t length) const { return length <= GetLength(); }

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

  // Unlike std::wstring::front(), this is always safe and returns a
  // NUL char when the string is empty.
  CharType Front() const { return m_pData ? m_pData->Front() : 0; }

  // Unlike std::wstring::back(), this is always safe and returns a
  // NUL char when the string is empty.
  CharType Back() const { return m_pData ? m_pData->Back() : 0; }

  // Holds on to buffer if possible for later re-use. Use assignment
  // to force immediate release if desired.
  void clear();

  // Increase the backing store of the string so that it is capable of storing
  // at least `nMinBufLength` chars. Returns a span to the entire buffer,
  // which may be larger than `nMinBufLength` due to rounding by allocators.
  // Note: any modification of the string (including ReleaseBuffer()) may
  // invalidate the span, which must not outlive its buffer.
  pdfium::span<T> GetBuffer(size_t nMinBufLength);

  // Sets the size of the string to `nNewLength` chars. Call this after a call
  // to GetBuffer(), to indicate how much of the buffer was actually used.
  void ReleaseBuffer(size_t nNewLength);

  // Returns size of string following insertion.
  size_t Insert(size_t index, T ch);
  size_t InsertAtFront(T ch) { return Insert(0, ch); }
  size_t InsertAtBack(T ch) { return Insert(GetLength(), ch); }

  // Returns number of instances of `ch` removed.
  size_t Remove(T ch);

  // Returns size of the string following deletion.
  size_t Delete(size_t index, size_t count = 1);

  // Returns the index within the string when found.
  std::optional<size_t> Find(StringView str, size_t start = 0) const;
  std::optional<size_t> Find(T ch, size_t start = 0) const;
  std::optional<size_t> ReverseFind(T ch) const;

  bool Contains(StringView str, size_t start = 0) const {
    return Find(str, start).has_value();
  }
  bool Contains(T ch, size_t start = 0) const {
    return Find(ch, start).has_value();
  }

  // Replace all occurences of `oldstr' with `newstr'.
  size_t Replace(StringView oldstr, StringView newstr);

  // Overwrite character at `index`.
  void SetAt(size_t index, T ch);

  void Reserve(size_t len) { GetBuffer(len); }

  // Remove character `ch` from  both/front/back of string.
  void Trim(T ch);
  void TrimFront(T ch);
  void TrimBack(T ch);

  // Remove all characters in `targets` from both/front/back of string.
  void Trim(StringView targets);
  void TrimFront(StringView targets);
  void TrimBack(StringView targets);

 protected:
  using StringData = StringDataTemplate<T>;

  StringTemplate() = default;
  StringTemplate(const StringTemplate& other) = default;

  // Move-construct a StringTemplate. After construction, |other| is empty.
  StringTemplate(StringTemplate&& other) noexcept = default;

  ~StringTemplate() = default;

  void ReallocBeforeWrite(size_t nNewLen);
  void AllocBeforeWrite(size_t nNewLen);
  void AssignCopy(const T* pSrcData, size_t nSrcLen);
  void Concat(const T* pSrcData, size_t nSrcLen);

  RetainPtr<StringData> m_pData;
};

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

}  // namespace fxcrt

#endif  // CORE_FXCRT_STRING_TEMPLATE_H_
