// Copyright 2019 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 <algorithm>
#include <cstdarg>
#include <cstddef>
#include <cstring>
#include <span>
#include <string_view>
#include <type_traits>
#include <utility>

#include "pw_preprocessor/compiler.h"
#include "pw_status/status.h"
#include "pw_status/status_with_size.h"
#include "pw_string/to_string.h"

namespace pw {

// StringBuilder facilitates building formatted strings in a fixed-size buffer.
// StringBuilders are always null terminated (unless they are constructed with
// an empty buffer) and never overflow. Status is tracked for each operation and
// an overall status is maintained, which reflects the most recent error.
//
// A StringBuilder does not own the buffer it writes to. It can be used to write
// strings to any buffer. The StringBuffer template class, defined below,
// allocates a buffer alongside a StringBuilder.
//
// StringBuilder supports C++-style << output, similar to std::ostringstream. It
// also supports std::string-like append functions and printf-style output.
//
// Support for custom types is added by overloading operator<< in the same
// namespace as the custom type. For example:
//
//   namespace my_project {
//
//   struct MyType {
//     int foo;
//     const char* bar;
//   };
//
//   pw::StringBuilder& operator<<(pw::StringBuilder& sb, const MyType& value) {
//     return sb << "MyType(" << value.foo << ", " << value.bar << ')';
//   }
//
//   }  // namespace my_project
//
// The ToString template function can be specialized to support custom types
// with StringBuilder, though overloading operator<< is generally preferred. For
// example:
//
//   namespace pw {
//
//   template <>
//   StatusWithSize ToString<MyStatus>(MyStatus value, std::span<char> buffer) {
//     return Copy(MyStatusString(value), buffer);
//   }
//
//   }  // namespace pw
//
class StringBuilder {
 public:
  // Creates an empty StringBuilder.
  constexpr StringBuilder(std::span<char> buffer) : buffer_(buffer), size_(0) {
    NullTerminate();
  }
  StringBuilder(std::span<std::byte> buffer)
      : StringBuilder(
            {reinterpret_cast<char*>(buffer.data()), buffer.size_bytes()}) {}

  // Disallow copy/assign to avoid confusion about where the string is actually
  // stored. StringBuffers may be copied into one another.
  StringBuilder(const StringBuilder&) = delete;

  StringBuilder& operator=(const StringBuilder&) = delete;

  // Returns the contents of the string buffer. Always null-terminated.
  const char* data() const { return buffer_.data(); }
  const char* c_str() const { return data(); }

  // Returns a std::string_view of the contents of this StringBuilder. The
  // std::string_view is invalidated if the StringBuilder contents change.
  std::string_view view() const { return std::string_view(data(), size()); }

  // Allow implicit conversions to std::string_view so StringBuilders can be
  // passed into functions that take a std::string_view.
  operator std::string_view() const { return view(); }

  // Returns a std::span<const std::byte> representation of this StringBuffer.
  std::span<const std::byte> as_bytes() const {
    return std::span(reinterpret_cast<const std::byte*>(buffer_.data()), size_);
  }

  // Returns the StringBuilder's status, which reflects the most recent error
  // that occurred while updating the string. After an update fails, the status
  // remains non-OK until it is cleared with clear() or clear_status(). Returns:
  //
  //     OK if no errors have occurred
  //     RESOURCE_EXHAUSTED if output to the StringBuilder was truncated
  //     INVALID_ARGUMENT if printf-style formatting failed
  //     OUT_OF_RANGE if an operation outside the buffer was attempted
  //
  Status status() const { return status_; }

  // Returns status() and size() as a StatusWithSize.
  StatusWithSize status_with_size() const {
    return StatusWithSize(status_, size_);
  }

  // The status from the last operation. May be OK while status() is not OK.
  Status last_status() const { return last_status_; }

  // True if status() is OkStatus().
  bool ok() const { return status_.ok(); }

  // True if the string is empty.
  bool empty() const { return size() == 0u; }

  // Returns the current length of the string, excluding the null terminator.
  size_t size() const { return size_; }

  // Returns the maximum length of the string, excluding the null terminator.
  size_t max_size() const { return buffer_.empty() ? 0u : buffer_.size() - 1; }

  // Clears the string and resets its error state.
  void clear();

  // Sets the statuses to OkStatus();
  void clear_status() {
    status_ = OkStatus();
    last_status_ = OkStatus();
  }

  // Appends a single character. Stets the status to RESOURCE_EXHAUSTED if the
  // character cannot be added because the buffer is full.
  void push_back(char ch) { append(1, ch); }

  // Removes the last character. Sets the status to OUT_OF_RANGE if the buffer
  // is empty (in which case the unsigned overflow is intentional).
  void pop_back() PW_NO_SANITIZE("unsigned-integer-overflow") {
    resize(size() - 1);
  }

  // Appends the provided character count times.
  StringBuilder& append(size_t count, char ch);

  // Appends count characters from str to the end of the StringBuilder. If count
  // exceeds the remaining space in the StringBuffer, max_size() - size()
  // characters are appended and the status is set to RESOURCE_EXHAUSTED.
  //
  // str is not considered null-terminated and may contain null characters.
  StringBuilder& append(const char* str, size_t count);

  // Appends characters from the null-terminated string to the end of the
  // StringBuilder. If the string's length exceeds the remaining space in the
  // buffer, max_size() - size() characters are copied and the status is set to
  // RESOURCE_EXHAUSTED.
  //
  // This function uses string::Length instead of std::strlen to avoid unbounded
  // reads if the string is not null terminated.
  StringBuilder& append(const char* str);

  // Appends a std::string_view to the end of the StringBuilder.
  StringBuilder& append(const std::string_view& str);

  // Appends a substring from the std::string_view to the StringBuilder. Copies
  // up to count characters starting from pos to the end of the StringBuilder.
  // If pos > str.size(), sets the status to OUT_OF_RANGE.
  StringBuilder& append(const std::string_view& str,
                        size_t pos,
                        size_t count = std::string_view::npos);

  // Appends to the end of the StringBuilder using the << operator. This enables
  // C++ stream-style formatted to StringBuilders.
  template <typename T>
  StringBuilder& operator<<(const T& value) {
    // For std::string_view-compatible types, use the append function, which
    // gives smaller code size.
    if constexpr (std::is_convertible_v<T, std::string_view>) {
      append(value);
    } else if constexpr (std::is_convertible_v<T, std::span<const std::byte>>) {
      WriteBytes(value);
    } else {
      HandleStatusWithSize(ToString(value, buffer_.subspan(size_)));
    }
    return *this;
  }

  // Provide a few additional operator<< overloads that reduce code size.
  StringBuilder& operator<<(bool value) {
    return append(value ? "true" : "false");
  }

  StringBuilder& operator<<(char value) {
    push_back(value);
    return *this;
  }

  StringBuilder& operator<<(std::nullptr_t) {
    return append(string::kNullPointerString);
  }

  StringBuilder& operator<<(Status status) { return *this << status.str(); }

  // Appends a printf-style string to the end of the StringBuilder. If the
  // formatted string does not fit, the results are truncated and the status is
  // set to RESOURCE_EXHAUSTED.
  //
  // Internally, calls string::Format, which calls std::vsnprintf.
  PW_PRINTF_FORMAT(2, 3) StringBuilder& Format(const char* format, ...);

  // Appends a vsnprintf-style string with va_list arguments to the end of the
  // StringBuilder. If the formatted string does not fit, the results are
  // truncated and the status is set to RESOURCE_EXHAUSTED.
  //
  // Internally, calls string::Format, which calls std::vsnprintf.
  StringBuilder& FormatVaList(const char* format, va_list args);

  // Sets the StringBuilder's size. This function only truncates; if
  // new_size > size(), it sets status to OUT_OF_RANGE and does nothing.
  void resize(size_t new_size);

 protected:
  // Functions to support StringBuffer copies.
  constexpr StringBuilder(std::span<char> buffer, const StringBuilder& other)
      : buffer_(buffer),
        size_(other.size_),
        status_(other.status_),
        last_status_(other.last_status_) {}

  void CopySizeAndStatus(const StringBuilder& other);

 private:
  void WriteBytes(std::span<const std::byte> data);

  size_t ResizeAndTerminate(size_t chars_to_append);

  void HandleStatusWithSize(StatusWithSize written);

  constexpr void NullTerminate() {
    if (!buffer_.empty()) {
      buffer_[size_] = '\0';
    }
  }

  void SetErrorStatus(Status status);

  const std::span<char> buffer_;

  size_t size_;
  Status status_;
  Status last_status_;
};

// StringBuffers declare a buffer along with a StringBuilder. StringBuffer can
// be used as a statically allocated replacement for std::ostringstream or
// std::string. For example:
//
//   StringBuffer<32> str;
//   str << "The answer is " << number << "!";  // with number = 42
//   str.c_str();  // null terminated C string "The answer is 42."
//   str.view();   // std::string_view of "The answer is 42."
//
template <size_t kSizeBytes>
class StringBuffer : public StringBuilder {
 public:
  StringBuffer() : StringBuilder(buffer_) {}

  // StringBuffers of the same size may be copied and assigned into one another.
  StringBuffer(const StringBuffer& other) : StringBuilder(buffer_, other) {
    CopyContents(other);
  }

  // A smaller StringBuffer may be copied or assigned into a larger one.
  template <size_t kOtherSizeBytes>
  StringBuffer(const StringBuffer<kOtherSizeBytes>& other)
      : StringBuilder(buffer_, other) {
    static_assert(StringBuffer<kOtherSizeBytes>::max_size() <= max_size(),
                  "A StringBuffer cannot be copied into a smaller buffer");
    CopyContents(other);
  }

  template <size_t kOtherSizeBytes>
  StringBuffer& operator=(const StringBuffer<kOtherSizeBytes>& other) {
    assign<kOtherSizeBytes>(other);
    return *this;
  }

  StringBuffer& operator=(const StringBuffer& other) {
    assign<kSizeBytes>(other);
    return *this;
  }

  template <size_t kOtherSizeBytes>
  StringBuffer& assign(const StringBuffer<kOtherSizeBytes>& other) {
    static_assert(StringBuffer<kOtherSizeBytes>::max_size() <= max_size(),
                  "A StringBuffer cannot be copied into a smaller buffer");
    CopySizeAndStatus(other);
    CopyContents(other);
    return *this;
  }

  // Returns the maximum length of the string, excluding the null terminator.
  static constexpr size_t max_size() { return kSizeBytes - 1; }

  // Returns a StringBuffer<kSizeBytes>& instead of a generic StringBuilder& for
  // append calls and stream-style operations.
  template <typename... Args>
  StringBuffer& append(Args&&... args) {
    StringBuilder::append(std::forward<Args>(args)...);
    return *this;
  }

  template <typename T>
  StringBuffer& operator<<(T&& value) {
    static_cast<StringBuilder&>(*this) << std::forward<T>(value);
    return *this;
  }

 private:
  template <size_t kOtherSize>
  void CopyContents(const StringBuffer<kOtherSize>& other) {
    std::memcpy(buffer_, other.data(), other.size() + 1);  // include the \0
  }

  static_assert(kSizeBytes >= 1u, "StringBuffers must be at least 1 byte long");
  char buffer_[kSizeBytes];
};

namespace string_internal {

// Internal code for determining the default size of StringBuffers created with
// MakeString.
//
// StringBuffers created with MakeString default to at least 24 bytes. This is
// large enough to fit the largest 64-bit integer (20 digits plus a \0), rounded
// up to the nearest multiple of 4.
inline constexpr size_t kDefaultMinimumStringBufferSize = 24;

// By default, MakeString uses a buffer size large enough to fit all string
// literal arguments. ArgLength uses this value as an estimate of the number of
// characters needed to represent a non-string argument.
inline constexpr size_t kDefaultArgumentSize = 4;

// Returns a string literal's length or kDefaultArgumentSize for non-strings.
template <typename T>
constexpr size_t ArgLength() {
  using Arg = std::remove_reference_t<T>;

  // If the argument is an array of const char, assume it is a string literal.
  if constexpr (std::is_array_v<Arg>) {
    using Element = std::remove_reference_t<decltype(std::declval<Arg>()[0])>;

    if constexpr (std::is_same_v<Element, const char>) {
      return std::extent_v<Arg> > 0u ? std::extent_v<Arg> - 1 : size_t(0);
    }
  }

  return kDefaultArgumentSize;
}

// This function returns the default string buffer size used by MakeString.
template <typename... Args>
constexpr size_t DefaultStringBufferSize() {
  return std::max((size_t(1) + ... + ArgLength<Args>()),
                  kDefaultMinimumStringBufferSize);
}

// Internal version of MakeString with const reference arguments instead of
// deduced types, which include the lengths of string literals. Having this
// function can reduce code size.
template <size_t kBufferSize, typename... Args>
auto InitializeStringBuffer(const Args&... args) {
  return (StringBuffer<kBufferSize>() << ... << args);
}

}  // namespace string_internal

// Makes a StringBuffer with a string version of a series of values. This is
// useful for creating and initializing a StringBuffer or for conveniently
// getting a null-terminated string. For example:
//
//     LOG_INFO("The MAC address is %s", MakeString(mac_address).c_str());
//
// By default, the buffer size is 24 bytes, large enough to fit any 64-bit
// integer. If string literal arguments are provided, the default size will be
// large enough to fit them and a null terminator, plus 4 additional bytes for
// each argument. To use a fixed buffer size, set the kBufferSize template
// argument. For example:
//
//   // Creates a default-size StringBuffer (10 + 10 + 4 + 1 + 1 = 26 bytes).
//   auto sb = MakeString("1234567890", "1234567890", number, "!");
//
//   // Creates a 32-byte StringBuffer.
//   auto sb = MakeString<32>("1234567890", "1234567890", number, "!");
//
// Keep in mind that each argument to MakeString expands to a function call.
// MakeString may increase code size more than an equivalent pw::string::Format
// (or std::snprintf) call.
template <size_t kBufferSize = 0u, typename... Args>
auto MakeString(Args&&... args) {
  constexpr size_t kSize =
      kBufferSize == 0u ? string_internal::DefaultStringBufferSize<Args...>()
                        : kBufferSize;
  return string_internal::InitializeStringBuffer<kSize>(args...);
}

}  // namespace pw
