// Copyright 2022 The Pigweed Authors
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.
#pragma once

#include <cstddef>
#include <initializer_list>
#include <iterator>

#include "pw_assert/assert.h"
#include "pw_polyfill/standard.h"
#include "pw_preprocessor/compiler.h"
#include "pw_string/internal/string_impl.h"

// Messages to use in static_assert statements.
#define _PW_STRING_CAPACITY_TOO_SMALL_FOR_ARRAY                               \
  "The pw::InlineString's capacity is too small to hold the assigned string " \
  "literal or character array. When assigning a literal to a "                \
  "pw::InlineString, the pw::InlineString's capacity must account for the "   \
  "null terminator."

#define _PW_STRING_CAPACITY_TOO_SMALL_FOR_STRING                               \
  "When assigning one pw::InlineString with known capacity to another, the "   \
  "capacity of the destination pw::InlineString must be at least as large as " \
  "the source string."

namespace pw {

// pw::InlineBasicString<T, kCapacity> is a fixed-capacity version of
// std::basic_string.  It implements mostly the same API as std::basic_string,
// but the capacity of the string is fixed at construction and cannot grow.
// Attempting to increase the size beyond the capacity triggers an assert.
//
// A pw::InlineString alias of pw::InlineBasicString<char>, equivalent to
// std::string, is defined below.
//
// pw::InlineBasicString has a template parameter for the capacity, but the
// capacity does not have to be known to use the string. The
// pw::InlineBasicString template inherits from a pw::InlineBasicString
// specialization with capacity of the reserved value pw::InlineString<>::npos.
// The actual capacity is stored in a single word alongside the size. This
// allows code to work with strings of any capacity through a pw::InlineString<>
// or pw::InlineBasicString<T> reference.
template <typename T, string_impl::size_type kCapacity = string_impl::kGeneric>
class InlineBasicString final
    : public InlineBasicString<T, string_impl::kGeneric> {
 public:
  using typename InlineBasicString<T, string_impl::kGeneric>::value_type;
  using typename InlineBasicString<T, string_impl::kGeneric>::size_type;
  using typename InlineBasicString<T, string_impl::kGeneric>::difference_type;
  using typename InlineBasicString<T, string_impl::kGeneric>::reference;
  using typename InlineBasicString<T, string_impl::kGeneric>::const_reference;
  using typename InlineBasicString<T, string_impl::kGeneric>::pointer;
  using typename InlineBasicString<T, string_impl::kGeneric>::const_pointer;
  using typename InlineBasicString<T, string_impl::kGeneric>::iterator;
  using typename InlineBasicString<T, string_impl::kGeneric>::const_iterator;
  using typename InlineBasicString<T, string_impl::kGeneric>::reverse_iterator;
  using
      typename InlineBasicString<T,
                                 string_impl::kGeneric>::const_reverse_iterator;

  using InlineBasicString<T, string_impl::kGeneric>::npos;

  // Constructors

  constexpr InlineBasicString() noexcept
      : InlineBasicString<T, string_impl::kGeneric>(kCapacity), buffer_() {}

  constexpr InlineBasicString(size_type count, T ch) : InlineBasicString() {
    Fill(data(), ch, count);
  }

  template <size_type kOtherCapacity>
  constexpr InlineBasicString(const InlineBasicString<T, kOtherCapacity>& other,
                              size_type index,
                              size_type count = npos)
      : InlineBasicString() {
    CopySubstr(data(), other.data(), other.size(), index, count);
  }

  constexpr InlineBasicString(const T* string, size_type count)
      : InlineBasicString() {
    Copy(data(), string, count);
  }

  template <typename U,
            typename = string_impl::EnableIfNonArrayCharPointer<T, U>>
  constexpr InlineBasicString(U c_string)
      : InlineBasicString(
            c_string, string_impl::BoundedStringLength(c_string, kCapacity)) {}

  template <size_t kCharArraySize>
  constexpr InlineBasicString(const T (&array)[kCharArraySize])
      : InlineBasicString() {
    static_assert(
        kCharArraySize < string_impl::kGeneric && kCharArraySize <= kCapacity,
        _PW_STRING_CAPACITY_TOO_SMALL_FOR_ARRAY);
    Copy(data(), array, string_impl::ArrayStringLength(array));
  }

  template <typename InputIterator,
            typename = string_impl::EnableIfInputIterator<InputIterator>>
  constexpr InlineBasicString(InputIterator start, InputIterator finish)
      : InlineBasicString() {
    IteratorCopy(start, finish, data(), data() + max_size());
  }

  // Use the default copy for InlineBasicString with the same capacity.
  constexpr InlineBasicString(const InlineBasicString&) = default;

  // When copying from an InlineBasicString with a different capacity, check
  // that the destination capacity is at least as large as the source capacity.
  template <size_type kOtherCapacity>
  constexpr InlineBasicString(const InlineBasicString<T, kOtherCapacity>& other)
      : InlineBasicString(other.data(), other.size()) {
    static_assert(
        kOtherCapacity == string_impl::kGeneric || kOtherCapacity <= kCapacity,
        _PW_STRING_CAPACITY_TOO_SMALL_FOR_STRING);
  }

  constexpr InlineBasicString(std::initializer_list<T> list)
      : InlineBasicString(list.begin(), list.size()) {}

#if PW_CXX_STANDARD_IS_SUPPORTED(17)  // std::string_view is a C++17 feature
  template <typename StringView,
            typename = string_impl::EnableIfStringViewLike<T, StringView>>
  explicit constexpr InlineBasicString(const StringView& string)
      : InlineBasicString() {
    const std::basic_string_view<T> view = string;
    assign(view.data(), view.size());
  }

  template <typename StringView,
            typename = string_impl::EnableIfStringViewLike<T, StringView>>
  constexpr InlineBasicString(const StringView& string,
                              size_type index,
                              size_type count)
      : InlineBasicString() {
    const std::basic_string_view<T> view = string;
    CopySubstr(data(), view.data(), view.size(), index, count);
  }
#endif  // PW_CXX_STANDARD_IS_SUPPORTED(17)

  InlineBasicString(std::nullptr_t) = delete;  // Cannot construct from nullptr

  // Assignment operators

  constexpr InlineBasicString& operator=(const InlineBasicString& other) =
      default;

  // Checks capacity rather than current size.
  template <size_type kOtherCapacity>
  constexpr InlineBasicString& operator=(
      const InlineBasicString<T, kOtherCapacity>& other) {
    return assign<kOtherCapacity>(other);  // NOLINT
  }

  template <size_t kCharArraySize>
  constexpr InlineBasicString& operator=(const T (&array)[kCharArraySize]) {
    return assign<kCharArraySize>(array);  // NOLINT
  }

  // Use SFINAE to avoid ambiguity with the array overload.
  template <typename U,
            typename = string_impl::EnableIfNonArrayCharPointer<T, U>>
  constexpr InlineBasicString& operator=(U c_string) {
    return assign(c_string);  // NOLINT
  }

  constexpr InlineBasicString& operator=(T ch) {
    static_assert(kCapacity != 0,
                  "Cannot assign a character to pw::InlineString<0>");
    return assign(1, ch);  // NOLINT
  }

  constexpr InlineBasicString& operator=(std::initializer_list<T> list) {
    return assign(list);  // NOLINT
  }

#if PW_CXX_STANDARD_IS_SUPPORTED(17)  // std::string_view is a C++17 feature
  template <typename StringView,
            typename = string_impl::EnableIfStringViewLike<T, StringView>>
  constexpr InlineBasicString& operator=(const StringView& string) {
    return assign(string);  // NOLINT
  }
#endif  // PW_CXX_STANDARD_IS_SUPPORTED(17)

  constexpr InlineBasicString& operator=(std::nullptr_t) = delete;

  template <size_type kOtherCapacity>
  constexpr InlineBasicString& operator+=(
      const InlineBasicString<T, kOtherCapacity>& string) {
    return append(string);
  }

  constexpr InlineBasicString& operator+=(T character) {
    push_back(character);
    return *this;
  }

  template <size_t kCharArraySize>
  constexpr InlineBasicString& operator+=(const T (&array)[kCharArraySize]) {
    return append(array);
  }

  template <typename U,
            typename = string_impl::EnableIfNonArrayCharPointer<T, U>>
  constexpr InlineBasicString& operator+=(U c_string) {
    return append(c_string);
  }

  constexpr InlineBasicString& operator+=(std::initializer_list<T> list) {
    return append(list.begin(), list.size());
  }

#if PW_CXX_STANDARD_IS_SUPPORTED(17)  // std::string_view is a C++17 feature
  template <typename StringView,
            typename = string_impl::EnableIfStringViewLike<T, StringView>>
  constexpr InlineBasicString& operator+=(const StringView& string) {
    return append(string);
  }
#endif  // PW_CXX_STANDARD_IS_SUPPORTED(17)

  // The data() and size() functions are defined differently for the generic and
  // known-size specializations. This is to support using pw::InlineBasicString
  // in constexpr statements. This data() implementation simply returns the
  // underlying buffer. The generic-capacity data() function casts *this to
  // InlineBasicString<T, 0>, so is only constexpr when the capacity is actually
  // 0.
  constexpr pointer data() { return buffer_; }
  constexpr const_pointer data() const { return buffer_; }

  // Use the size() function from the base, but define max_size() to return the
  // kCapacity template parameter instead of reading the stored capacity value.
  using InlineBasicString<T, string_impl::kGeneric>::size;
  constexpr size_type max_size() const noexcept { return kCapacity; }

  // Most string functions are defined in separate file so they can be shared
  // between the known capacity and generic capacity versions of
  // InlineBasicString.
#include "pw_string/internal/string_common_functions.inc"

 private:
  using InlineBasicString<T, string_impl::kGeneric>::PushBack;
  using InlineBasicString<T, string_impl::kGeneric>::PopBack;
  using InlineBasicString<T, string_impl::kGeneric>::Copy;
  using InlineBasicString<T, string_impl::kGeneric>::CopySubstr;
  using InlineBasicString<T, string_impl::kGeneric>::Fill;
  using InlineBasicString<T, string_impl::kGeneric>::IteratorCopy;
  using InlineBasicString<T, string_impl::kGeneric>::CopyExtend;
  using InlineBasicString<T, string_impl::kGeneric>::CopyExtendSubstr;
  using InlineBasicString<T, string_impl::kGeneric>::FillExtend;
  using InlineBasicString<T, string_impl::kGeneric>::IteratorExtend;
  using InlineBasicString<T, string_impl::kGeneric>::Resize;
  using InlineBasicString<T, string_impl::kGeneric>::SetSizeAndTerminate;

  // Store kCapacity + 1 bytes to reserve space for a null terminator.
  // InlineBasicString<T, 0> only stores a null terminator.
  T buffer_[kCapacity + 1];
};

// Generic-capacity version of pw::InlineBasicString. Generic-capacity strings
// cannot be constructed; they can only be used as references to fixed-capacity
// pw::InlineBasicString objects.
template <typename T>
class InlineBasicString<T, string_impl::kGeneric> {
 public:
  using value_type = T;
  using size_type = string_impl::size_type;
  using difference_type = std::ptrdiff_t;
  using reference = value_type&;
  using const_reference = const value_type&;
  using pointer = value_type*;
  using const_pointer = const value_type*;
  using iterator = value_type*;
  using const_iterator = const value_type*;
  using reverse_iterator = std::reverse_iterator<iterator>;
  using const_reverse_iterator = std::reverse_iterator<const_iterator>;

  static constexpr size_type npos = string_impl::kGeneric;

  InlineBasicString() = delete;  // Must specify capacity to construct a string.

  // For the generic-capacity pw::InlineBasicString, cast this object to a
  // fixed-capacity class so the address of the data can be found. Even though
  // the capacity isn't known at compile time, the location of the data never
  // changes.
  constexpr pointer data() noexcept {
    return static_cast<InlineBasicString<T, 0>*>(this)->data();
  }
  constexpr const_pointer data() const noexcept {
    return static_cast<const InlineBasicString<T, 0>*>(this)->data();
  }

  constexpr size_type size() const noexcept { return length_; }
  constexpr size_type max_size() const noexcept { return capacity_; }

  // Most string functions are defined in separate file so they can be shared
  // between the known capacity and generic capacity versions of
  // InlineBasicString.
#include "pw_string/internal/string_common_functions.inc"

 protected:
  explicit constexpr InlineBasicString(size_type capacity)
      : capacity_(capacity), length_(0) {}

  // The generic-capacity InlineBasicString<T> is not copyable or movable, but
  // BasicStrings can copied or assigned through a fixed capacity derived class.
  InlineBasicString(const InlineBasicString&) = default;

  InlineBasicString& operator=(const InlineBasicString&) = default;

  constexpr void PushBack(T* data, T ch);

  constexpr void PopBack(T* data) {
    PW_ASSERT(!empty());
    SetSizeAndTerminate(data, size() - 1);
  }

  constexpr InlineBasicString& Copy(T* data,
                                    const T* source,
                                    size_type new_size);

  constexpr InlineBasicString& CopySubstr(T* data,
                                          const T* source,
                                          size_type source_size,
                                          size_type index,
                                          size_type count);

  constexpr InlineBasicString& Fill(T* data, T fill_char, size_type new_size);

  template <typename InputIterator>
  constexpr InlineBasicString& IteratorCopy(InputIterator start,
                                            InputIterator finish,
                                            T* data_start,
                                            const T* data_finish) {
    set_size(string_impl::IteratorCopyAndTerminate(
        start, finish, data_start, data_finish));
    return *this;
  }

  constexpr InlineBasicString& CopyExtend(T* data,
                                          const T* source,
                                          size_type count);

  constexpr InlineBasicString& CopyExtendSubstr(T* data,
                                                const T* source,
                                                size_type source_size,
                                                size_type index,
                                                size_type count);

  constexpr InlineBasicString& FillExtend(T* data,
                                          T fill_char,
                                          size_type count);

  template <typename InputIterator>
  constexpr InlineBasicString& IteratorExtend(InputIterator start,
                                              InputIterator finish,
                                              T* data_start,
                                              const T* data_finish) {
    length_ += string_impl::IteratorCopyAndTerminate(
        start, finish, data_start, data_finish);
    return *this;
  }

  constexpr void Resize(T* data, size_type new_size, T ch);

  constexpr void set_size(size_type length) { length_ = length; }
  constexpr void SetSizeAndTerminate(T* data, size_type length) {
    string_impl::char_traits<T>::assign(data[length], T());
    set_size(length);
  }

 private:
  // Provide this constant for static_assert checks. If the capacity is unknown,
  // use the maximum value so that compile-time capacity checks pass. If
  // overflow occurs, the operation triggers a PW_ASSERT at runtime.
  static constexpr size_type kCapacity = string_impl::kGeneric;

  size_type capacity_;
  size_type length_;
};

// Class template argument deduction guides

#ifdef __cpp_deduction_guides

// In C++17, the capacity of the string may be deduced from a string literal or
// array. For example, the following deduces a character type of char and a
// capacity of 5 (which includes the null terminator):
//
//   InlineBasicString my_string = "1234";
//
// In C++20, the template parameters for the pw::InlineString alias may be
// deduced similarly:
//
//   InlineString my_string = "abc";  // deduces capacity of 4.
//
template <typename T, size_t kCharArraySize>
InlineBasicString(const T (&)[kCharArraySize])
    -> InlineBasicString<T, kCharArraySize>;

#endif  // __cpp_deduction_guides

// Operators

// TODO(b/239996007): Implement operator+

template <typename T,
          string_impl::size_type kLhsCapacity,
          string_impl::size_type kRhsCapacity>
constexpr bool operator==(
    const InlineBasicString<T, kLhsCapacity>& lhs,
    const InlineBasicString<T, kRhsCapacity>& rhs) noexcept {
  return lhs.compare(rhs) == 0;
}

template <typename T,
          string_impl::size_type kLhsCapacity,
          string_impl::size_type kRhsCapacity>
constexpr bool operator!=(
    const InlineBasicString<T, kLhsCapacity>& lhs,
    const InlineBasicString<T, kRhsCapacity>& rhs) noexcept {
  return lhs.compare(rhs) != 0;
}

template <typename T,
          string_impl::size_type kLhsCapacity,
          string_impl::size_type kRhsCapacity>
constexpr bool operator<(
    const InlineBasicString<T, kLhsCapacity>& lhs,
    const InlineBasicString<T, kRhsCapacity>& rhs) noexcept {
  return lhs.compare(rhs) < 0;
}

template <typename T,
          string_impl::size_type kLhsCapacity,
          string_impl::size_type kRhsCapacity>
constexpr bool operator<=(
    const InlineBasicString<T, kLhsCapacity>& lhs,
    const InlineBasicString<T, kRhsCapacity>& rhs) noexcept {
  return lhs.compare(rhs) <= 0;
}

template <typename T,
          string_impl::size_type kLhsCapacity,
          string_impl::size_type kRhsCapacity>
constexpr bool operator>(
    const InlineBasicString<T, kLhsCapacity>& lhs,
    const InlineBasicString<T, kRhsCapacity>& rhs) noexcept {
  return lhs.compare(rhs) > 0;
}

template <typename T,
          string_impl::size_type kLhsCapacity,
          string_impl::size_type kRhsCapacity>
constexpr bool operator>=(
    const InlineBasicString<T, kLhsCapacity>& lhs,
    const InlineBasicString<T, kRhsCapacity>& rhs) noexcept {
  return lhs.compare(rhs) >= 0;
}

// TODO(b/239996007): Implement other comparison operator overloads.

// Aliases
template <string_impl::size_type kCapacity = string_impl::kGeneric>
using InlineString = InlineBasicString<char, kCapacity>;

// Function implementations

template <typename T>
constexpr void InlineBasicString<T, string_impl::kGeneric>::PushBack(T* data,
                                                                     T ch) {
  PW_ASSERT(size() < max_size());
  string_impl::char_traits<T>::assign(data[size()], ch);
  SetSizeAndTerminate(data, size() + 1);
}

template <typename T>
constexpr InlineBasicString<T, string_impl::kGeneric>&
InlineBasicString<T, string_impl::kGeneric>::Copy(T* data,
                                                  const T* source,
                                                  size_type new_size) {
  PW_ASSERT(new_size <= max_size());
  string_impl::char_traits<T>::copy(data, source, new_size);
  SetSizeAndTerminate(data, new_size);
  return *this;
}

template <typename T>
constexpr InlineBasicString<T, string_impl::kGeneric>&
InlineBasicString<T, string_impl::kGeneric>::CopySubstr(T* data,
                                                        const T* source,
                                                        size_type source_size,
                                                        size_type index,
                                                        size_type count) {
  PW_ASSERT(index <= source_size);
  return Copy(data,
              source + index,
              std::min(count, static_cast<size_type>(source_size - index)));
}

template <typename T>
constexpr InlineBasicString<T, string_impl::kGeneric>&
InlineBasicString<T, string_impl::kGeneric>::Fill(T* data,
                                                  T fill_char,
                                                  size_type new_size) {
  PW_ASSERT(new_size <= max_size());
  string_impl::char_traits<T>::assign(data, new_size, fill_char);
  SetSizeAndTerminate(data, new_size);
  return *this;
}

template <typename T>
constexpr InlineBasicString<T, string_impl::kGeneric>&
InlineBasicString<T, string_impl::kGeneric>::CopyExtend(T* data,
                                                        const T* source,
                                                        size_type count) {
  PW_ASSERT(count <= max_size() - size());
  string_impl::char_traits<T>::copy(data + size(), source, count);
  SetSizeAndTerminate(data, size() + count);
  return *this;
}

template <typename T>
constexpr InlineBasicString<T, string_impl::kGeneric>&
InlineBasicString<T, string_impl::kGeneric>::CopyExtendSubstr(
    T* data,
    const T* source,
    size_type source_size,
    size_type index,
    size_type count) {
  PW_ASSERT(index <= source_size);
  return CopyExtend(
      data,
      source + index,
      std::min(count, static_cast<size_type>(source_size - index)));
  return *this;
}

template <typename T>
constexpr InlineBasicString<T, string_impl::kGeneric>&
InlineBasicString<T, string_impl::kGeneric>::FillExtend(T* data,
                                                        T fill_char,
                                                        size_type count) {
  PW_ASSERT(count <= max_size() - size());
  string_impl::char_traits<T>::assign(data + size(), count, fill_char);
  SetSizeAndTerminate(data, size() + count);
  return *this;
}

template <typename T>
constexpr void InlineBasicString<T, string_impl::kGeneric>::Resize(
    T* data, size_type new_size, T ch) {
  PW_ASSERT(new_size <= max_size());

  if (new_size > size()) {
    string_impl::char_traits<T>::assign(data + size(), new_size - size(), ch);
  }

  SetSizeAndTerminate(data, new_size);
}

}  // namespace pw

#undef _PW_STRING_CAPACITY_TOO_SMALL_FOR_ARRAY
#undef _PW_STRING_CAPACITY_TOO_SMALL_FOR_STRING
