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

#include <functional>
#include <sstream>
#include <utility>

#include "core/fxcrt/cfx_retain_ptr.h"
#include "core/fxcrt/cfx_string_c_template.h"
#include "core/fxcrt/cfx_string_data_template.h"
#include "core/fxcrt/fx_system.h"
#include "third_party/base/optional.h"

class CFX_WideString;

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

  CFX_ByteString();
  CFX_ByteString(const CFX_ByteString& other);
  CFX_ByteString(CFX_ByteString&& other) noexcept;

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

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

  CFX_ByteString(const char* ptr, FX_STRSIZE len);
  CFX_ByteString(const uint8_t* ptr, FX_STRSIZE len);

  explicit CFX_ByteString(const CFX_ByteStringC& bstrc);
  CFX_ByteString(const CFX_ByteStringC& bstrc1, const CFX_ByteStringC& bstrc2);
  CFX_ByteString(const std::initializer_list<CFX_ByteStringC>& list);
  explicit CFX_ByteString(const std::ostringstream& outStream);

  ~CFX_ByteString();

  void clear() { m_pData.Reset(); }

  static CFX_ByteString FromUnicode(const CFX_WideString& str);

  // Explicit conversion to C-style string.
  // 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*.
  // 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 CFX_ByteStringC.
  // Note: Any subsequent modification of |this| will invalidate the result.
  CFX_ByteStringC AsStringC() const {
    return CFX_ByteStringC(raw_str(), GetLength());
  }

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

  FX_STRSIZE GetLength() const { return m_pData ? m_pData->m_nDataLength : 0; }
  FX_STRSIZE GetStringLength() const {
    return m_pData ? FXSYS_strlen(m_pData->m_String) : 0;
  }
  bool IsEmpty() const { return !GetLength(); }

  bool IsValidIndex(FX_STRSIZE index) const {
    return 0 <= index && index < GetLength();
  }

  bool IsValidLength(FX_STRSIZE length) const {
    return 0 <= length && length <= GetLength();
  }

  int Compare(const CFX_ByteStringC& str) const;
  bool EqualNoCase(const CFX_ByteStringC& str) const;

  bool operator==(const char* ptr) const;
  bool operator==(const CFX_ByteStringC& str) const;
  bool operator==(const CFX_ByteString& other) const;

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

  bool operator<(const CFX_ByteString& str) const;

  const CFX_ByteString& operator=(const char* str);
  const CFX_ByteString& operator=(const CFX_ByteStringC& bstrc);
  const CFX_ByteString& operator=(const CFX_ByteString& stringSrc);

  const CFX_ByteString& operator+=(char ch);
  const CFX_ByteString& operator+=(const char* str);
  const CFX_ByteString& operator+=(const CFX_ByteString& str);
  const CFX_ByteString& operator+=(const CFX_ByteStringC& bstrc);

  CharType operator[](const FX_STRSIZE index) const {
    ASSERT(IsValidIndex(index));
    return m_pData ? m_pData->m_String[index] : 0;
  }

  CharType First() const { return GetLength() ? (*this)[0] : 0; }
  CharType Last() const { return GetLength() ? (*this)[GetLength() - 1] : 0; }

  void SetAt(FX_STRSIZE index, char c);

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

  void Format(const char* lpszFormat, ...);
  void FormatV(const char* lpszFormat, va_list argList);

  void Reserve(FX_STRSIZE len);
  char* GetBuffer(FX_STRSIZE len);
  void ReleaseBuffer(FX_STRSIZE len);

  CFX_ByteString Mid(FX_STRSIZE first, FX_STRSIZE count) const;
  CFX_ByteString Left(FX_STRSIZE count) const;
  CFX_ByteString Right(FX_STRSIZE count) const;

  pdfium::Optional<FX_STRSIZE> Find(const CFX_ByteStringC& lpszSub,
                                    FX_STRSIZE start = 0) const;
  pdfium::Optional<FX_STRSIZE> Find(char ch, FX_STRSIZE start = 0) const;
  pdfium::Optional<FX_STRSIZE> ReverseFind(char ch) const;

  bool Contains(const CFX_ByteStringC& lpszSub, FX_STRSIZE start = 0) const {
    return Find(lpszSub, start).has_value();
  }

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

  void MakeLower();
  void MakeUpper();

  void TrimRight();
  void TrimRight(char chTarget);
  void TrimRight(const CFX_ByteStringC& lpszTargets);

  void TrimLeft();
  void TrimLeft(char chTarget);
  void TrimLeft(const CFX_ByteStringC& lpszTargets);

  FX_STRSIZE Replace(const CFX_ByteStringC& lpszOld,
                     const CFX_ByteStringC& lpszNew);

  FX_STRSIZE Remove(char ch);

  CFX_WideString UTF8Decode() const;

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

  static CFX_ByteString FormatInteger(int i);
  static CFX_ByteString FormatFloat(float f, int precision = 0);

 protected:
  using StringData = CFX_StringDataTemplate<char>;

  void ReallocBeforeWrite(FX_STRSIZE nNewLen);
  void AllocBeforeWrite(FX_STRSIZE nNewLen);
  void AllocCopy(CFX_ByteString& dest,
                 FX_STRSIZE nCopyLen,
                 FX_STRSIZE nCopyIndex) const;
  void AssignCopy(const char* pSrcData, FX_STRSIZE nSrcLen);
  void Concat(const char* lpszSrcData, FX_STRSIZE nSrcLen);

  CFX_RetainPtr<StringData> m_pData;

  friend class fxcrt_ByteStringConcat_Test;
  friend class fxcrt_ByteStringPool_Test;
};

inline bool operator==(const char* lhs, const CFX_ByteString& rhs) {
  return rhs == lhs;
}
inline bool operator==(const CFX_ByteStringC& lhs, const CFX_ByteString& rhs) {
  return rhs == lhs;
}
inline bool operator!=(const char* lhs, const CFX_ByteString& rhs) {
  return rhs != lhs;
}
inline bool operator!=(const CFX_ByteStringC& lhs, const CFX_ByteString& rhs) {
  return rhs != lhs;
}

inline CFX_ByteString operator+(const CFX_ByteStringC& str1,
                                const CFX_ByteStringC& str2) {
  return CFX_ByteString(str1, str2);
}
inline CFX_ByteString operator+(const CFX_ByteStringC& str1, const char* str2) {
  return CFX_ByteString(str1, str2);
}
inline CFX_ByteString operator+(const char* str1, const CFX_ByteStringC& str2) {
  return CFX_ByteString(str1, str2);
}
inline CFX_ByteString operator+(const CFX_ByteStringC& str1, char ch) {
  return CFX_ByteString(str1, CFX_ByteStringC(ch));
}
inline CFX_ByteString operator+(char ch, const CFX_ByteStringC& str2) {
  return CFX_ByteString(ch, str2);
}
inline CFX_ByteString operator+(const CFX_ByteString& str1,
                                const CFX_ByteString& str2) {
  return CFX_ByteString(str1.AsStringC(), str2.AsStringC());
}
inline CFX_ByteString operator+(const CFX_ByteString& str1, char ch) {
  return CFX_ByteString(str1.AsStringC(), CFX_ByteStringC(ch));
}
inline CFX_ByteString operator+(char ch, const CFX_ByteString& str2) {
  return CFX_ByteString(ch, str2.AsStringC());
}
inline CFX_ByteString operator+(const CFX_ByteString& str1, const char* str2) {
  return CFX_ByteString(str1.AsStringC(), str2);
}
inline CFX_ByteString operator+(const char* str1, const CFX_ByteString& str2) {
  return CFX_ByteString(str1, str2.AsStringC());
}
inline CFX_ByteString operator+(const CFX_ByteString& str1,
                                const CFX_ByteStringC& str2) {
  return CFX_ByteString(str1.AsStringC(), str2);
}
inline CFX_ByteString operator+(const CFX_ByteStringC& str1,
                                const CFX_ByteString& str2) {
  return CFX_ByteString(str1, str2.AsStringC());
}

uint32_t FX_HashCode_GetA(const CFX_ByteStringC& str, bool bIgnoreCase);

std::ostream& operator<<(std::ostream& os, const CFX_ByteString& str);
std::ostream& operator<<(std::ostream& os, const CFX_ByteStringC& str);

namespace std {

template <>
struct hash<CFX_ByteString> {
  std::size_t operator()(const CFX_ByteString& str) const {
    return FX_HashCode_GetA(str.AsStringC(), false);
  }
};

}  // namespace std

extern template struct std::hash<CFX_ByteString>;

#endif  // CORE_FXCRT_CFX_BYTESTRING_H_
