// Copyright 2017 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_BYTESTRING_H_
#define CORE_FXCRT_BYTESTRING_H_

#include <stdarg.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>

#include <functional>
#include <iosfwd>
#include <iterator>
#include <optional>
#include <utility>

#include "core/fxcrt/fx_string_wrappers.h"
#include "core/fxcrt/retain_ptr.h"
#include "core/fxcrt/string_data_template.h"
#include "core/fxcrt/string_view_template.h"
#include "third_party/base/check.h"
#include "third_party/base/containers/span.h"

namespace fxcrt {

// A mutable string with shared buffers using copy-on-write semantics that
// avoids the cost of std::string's iterator stability guarantees.
class ByteString {
 public:
  using CharType = char;
  using const_iterator = const CharType*;
  using const_reverse_iterator = std::reverse_iterator<const_iterator>;

  [[nodiscard]] static ByteString FormatInteger(int i);
  [[nodiscard]] static ByteString FormatFloat(float f);
  [[nodiscard]] static ByteString Format(const char* pFormat, ...);
  [[nodiscard]] static ByteString FormatV(const char* pFormat, va_list argList);

  ByteString();
  ByteString(const ByteString& other);

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

  // Make a one-character string from a char.
  explicit ByteString(char ch);

  // Deliberately implicit to avoid calling on every string literal.
  // NOLINTNEXTLINE(runtime/explicit)
  ByteString(const char* ptr);

  // No implicit conversions from wide strings.
  // NOLINTNEXTLINE(runtime/explicit)
  ByteString(wchar_t) = delete;

  ByteString(const char* pStr, size_t len);
  ByteString(const uint8_t* pStr, size_t len);

  explicit ByteString(ByteStringView bstrc);
  ByteString(ByteStringView str1, ByteStringView str2);
  ByteString(const std::initializer_list<ByteStringView>& list);
  explicit ByteString(const fxcrt::ostringstream& outStream);

  ~ByteString();

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

  // Explicit conversion to C-style string. The result is never nullptr,
  // and is always NUL terminated.
  // Note: Any subsequent modification of |this| will invalidate the result.
  const char* c_str() const { return m_pData ? m_pData->m_String : ""; }

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

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

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

  size_t GetLength() const { return m_pData ? m_pData->m_nDataLength : 0; }
  size_t GetStringLength() const {
    return m_pData ? strlen(m_pData->m_String) : 0;
  }
  bool IsEmpty() const { return !GetLength(); }
  bool IsValidIndex(size_t index) const { return index < GetLength(); }
  bool IsValidLength(size_t length) const { return length <= GetLength(); }

  int Compare(ByteStringView str) const;
  bool EqualNoCase(ByteStringView str) const;

  bool operator==(const char* ptr) const;
  bool operator==(ByteStringView str) const;
  bool operator==(const ByteString& other) const;

  bool operator!=(const char* ptr) const { return !(*this == ptr); }
  bool operator!=(ByteStringView str) const { return !(*this == str); }
  bool operator!=(const ByteString& other) const { return !(*this == other); }

  bool operator<(const char* ptr) const;
  bool operator<(ByteStringView str) const;
  bool operator<(const ByteString& other) const;

  ByteString& operator=(const char* str);
  ByteString& operator=(ByteStringView str);
  ByteString& operator=(const ByteString& that);

  // Move-assign a ByteString. After assignment, |that| is empty.
  ByteString& operator=(ByteString&& that) noexcept;

  ByteString& operator+=(char ch);
  ByteString& operator+=(const char* str);
  ByteString& operator+=(const ByteString& str);
  ByteString& operator+=(ByteStringView str);

  // 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::string::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::string::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; }

  void SetAt(size_t index, char c);

  size_t Insert(size_t index, char ch);
  size_t InsertAtFront(char ch) { return Insert(0, ch); }
  size_t InsertAtBack(char ch) { return Insert(GetLength(), ch); }
  size_t Delete(size_t index, size_t count = 1);

  void Reserve(size_t len);

  // 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<char> 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);

  ByteString Substr(size_t offset) const;
  ByteString Substr(size_t first, size_t count) const;
  ByteString First(size_t count) const;
  ByteString Last(size_t count) const;

  std::optional<size_t> Find(ByteStringView subStr, size_t start = 0) const;
  std::optional<size_t> Find(char ch, size_t start = 0) const;
  std::optional<size_t> ReverseFind(char ch) const;

  bool Contains(ByteStringView lpszSub, size_t start = 0) const {
    return Find(lpszSub, start).has_value();
  }

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

  void MakeLower();
  void MakeUpper();

  void Trim();
  void Trim(char target);
  void Trim(ByteStringView targets);

  void TrimLeft();
  void TrimLeft(char target);
  void TrimLeft(ByteStringView targets);

  void TrimRight();
  void TrimRight(char target);
  void TrimRight(ByteStringView targets);

  size_t Replace(ByteStringView pOld, ByteStringView pNew);
  size_t Remove(char ch);

  uint32_t GetID() const { return AsStringView().GetID(); }

 protected:
  using StringData = StringDataTemplate<char>;

  void ReallocBeforeWrite(size_t nNewLen);
  void AllocBeforeWrite(size_t nNewLen);
  void AssignCopy(const char* pSrcData, size_t nSrcLen);
  void Concat(const char* pSrcData, size_t nSrcLen);
  intptr_t ReferenceCountForTesting() const;

  RetainPtr<StringData> m_pData;

  friend class ByteString_Assign_Test;
  friend class ByteString_Concat_Test;
  friend class ByteString_Construct_Test;
  friend class StringPool_ByteString_Test;
};

inline bool operator==(const char* lhs, const ByteString& rhs) {
  return rhs == lhs;
}
inline bool operator==(ByteStringView lhs, const ByteString& rhs) {
  return rhs == lhs;
}
inline bool operator!=(const char* lhs, const ByteString& rhs) {
  return rhs != lhs;
}
inline bool operator!=(ByteStringView lhs, const ByteString& rhs) {
  return rhs != lhs;
}
inline bool operator<(const char* lhs, const ByteString& rhs) {
  return rhs.Compare(lhs) > 0;
}
inline bool operator<(const ByteStringView& lhs, const ByteString& rhs) {
  return rhs.Compare(lhs) > 0;
}
inline bool operator<(const ByteStringView& lhs, const char* rhs) {
  return lhs < ByteStringView(rhs);
}

inline ByteString operator+(ByteStringView str1, ByteStringView str2) {
  return ByteString(str1, str2);
}
inline ByteString operator+(ByteStringView str1, const char* str2) {
  return ByteString(str1, str2);
}
inline ByteString operator+(const char* str1, ByteStringView str2) {
  return ByteString(str1, str2);
}
inline ByteString operator+(ByteStringView str1, char ch) {
  return ByteString(str1, ByteStringView(ch));
}
inline ByteString operator+(char ch, ByteStringView str2) {
  return ByteString(ByteStringView(ch), str2);
}
inline ByteString operator+(const ByteString& str1, const ByteString& str2) {
  return ByteString(str1.AsStringView(), str2.AsStringView());
}
inline ByteString operator+(const ByteString& str1, char ch) {
  return ByteString(str1.AsStringView(), ByteStringView(ch));
}
inline ByteString operator+(char ch, const ByteString& str2) {
  return ByteString(ByteStringView(ch), str2.AsStringView());
}
inline ByteString operator+(const ByteString& str1, const char* str2) {
  return ByteString(str1.AsStringView(), str2);
}
inline ByteString operator+(const char* str1, const ByteString& str2) {
  return ByteString(str1, str2.AsStringView());
}
inline ByteString operator+(const ByteString& str1, ByteStringView str2) {
  return ByteString(str1.AsStringView(), str2);
}
inline ByteString operator+(ByteStringView str1, const ByteString& str2) {
  return ByteString(str1, str2.AsStringView());
}

std::ostream& operator<<(std::ostream& os, const ByteString& str);
std::ostream& operator<<(std::ostream& os, ByteStringView str);

// This is declared here for use in gtest-based tests but is defined in a test
// support target. This should not be used in production code. Just use
// operator<< from above instead.
// In some cases, gtest will automatically use operator<< as well, but in this
// case, it needs PrintTo() because ByteString looks like a container to gtest.
void PrintTo(const ByteString& str, std::ostream* os);

}  // namespace fxcrt

using ByteString = fxcrt::ByteString;

uint32_t FX_HashCode_GetA(ByteStringView str);
uint32_t FX_HashCode_GetLoweredA(ByteStringView str);
uint32_t FX_HashCode_GetAsIfW(ByteStringView str);
uint32_t FX_HashCode_GetLoweredAsIfW(ByteStringView str);

namespace std {

template <>
struct hash<ByteString> {
  size_t operator()(const ByteString& str) const {
    return FX_HashCode_GetA(str.AsStringView());
  }
};

}  // namespace std

extern template struct std::hash<ByteString>;

#endif  // CORE_FXCRT_BYTESTRING_H_
