/*
 *  Copyright 2018 The WebRTC Project Authors. All rights reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "rtc_base/strings/string_builder.h"

#include <stdarg.h>

#include <cstdio>
#include <cstring>

#include "rtc_base/checks.h"
#include "rtc_base/numerics/safe_minmax.h"

namespace rtc {

SimpleStringBuilder::SimpleStringBuilder(rtc::ArrayView<char> buffer)
    : buffer_(buffer) {
  buffer_[0] = '\0';
  RTC_DCHECK(IsConsistent());
}

SimpleStringBuilder& SimpleStringBuilder::operator<<(const char* str) {
  return Append(str, strlen(str));
}

SimpleStringBuilder& SimpleStringBuilder::operator<<(char ch) {
  return Append(&ch, 1);
}

SimpleStringBuilder& SimpleStringBuilder::operator<<(const std::string& str) {
  return Append(str.c_str(), str.length());
}

// Numeric conversion routines.
//
// We use std::[v]snprintf instead of std::to_string because:
// * std::to_string relies on the current locale for formatting purposes,
//   and therefore concurrent calls to std::to_string from multiple threads
//   may result in partial serialization of calls
// * snprintf allows us to print the number directly into our buffer.
// * avoid allocating a std::string (potential heap alloc).
// TODO(tommi): Switch to std::to_chars in C++17.

SimpleStringBuilder& SimpleStringBuilder::operator<<(int i) {
  return AppendFormat("%d", i);
}

SimpleStringBuilder& SimpleStringBuilder::operator<<(unsigned i) {
  return AppendFormat("%u", i);
}

SimpleStringBuilder& SimpleStringBuilder::operator<<(long i) {  // NOLINT
  return AppendFormat("%ld", i);
}

SimpleStringBuilder& SimpleStringBuilder::operator<<(long long i) {  // NOLINT
  return AppendFormat("%lld", i);
}

SimpleStringBuilder& SimpleStringBuilder::operator<<(
    unsigned long i) {  // NOLINT
  return AppendFormat("%lu", i);
}

SimpleStringBuilder& SimpleStringBuilder::operator<<(
    unsigned long long i) {  // NOLINT
  return AppendFormat("%llu", i);
}

SimpleStringBuilder& SimpleStringBuilder::operator<<(float f) {
  return AppendFormat("%g", f);
}

SimpleStringBuilder& SimpleStringBuilder::operator<<(double f) {
  return AppendFormat("%g", f);
}

SimpleStringBuilder& SimpleStringBuilder::operator<<(long double f) {
  return AppendFormat("%Lg", f);
}

SimpleStringBuilder& SimpleStringBuilder::AppendFormat(const char* fmt, ...) {
  va_list args;
  va_start(args, fmt);
  const int len =
      std::vsnprintf(&buffer_[size_], buffer_.size() - size_, fmt, args);
  if (len >= 0) {
    const size_t chars_added = rtc::SafeMin(len, buffer_.size() - 1 - size_);
    size_ += chars_added;
    RTC_DCHECK_EQ(len, chars_added) << "Buffer size was insufficient";
  } else {
    // This should never happen, but we're paranoid, so re-write the
    // terminator in case vsnprintf() overwrote it.
    RTC_NOTREACHED();
    buffer_[size_] = '\0';
  }
  va_end(args);
  RTC_DCHECK(IsConsistent());
  return *this;
}

SimpleStringBuilder& SimpleStringBuilder::Append(const char* str,
                                                 size_t length) {
  RTC_DCHECK_LT(size_ + length, buffer_.size())
      << "Buffer size was insufficient";
  const size_t chars_added = rtc::SafeMin(length, buffer_.size() - size_ - 1);
  memcpy(&buffer_[size_], str, chars_added);
  size_ += chars_added;
  buffer_[size_] = '\0';
  RTC_DCHECK(IsConsistent());
  return *this;
}

StringBuilder& StringBuilder::AppendFormat(const char* fmt, ...) {
  va_list args, copy;
  va_start(args, fmt);
  va_copy(copy, args);
  const int predicted_length = std::vsnprintf(nullptr, 0, fmt, copy);
  va_end(copy);

  RTC_DCHECK_GE(predicted_length, 0);
  if (predicted_length > 0) {
    const size_t size = str_.size();
    str_.resize(size + predicted_length);
    // Pass "+ 1" to vsnprintf to include space for the '\0'.
    const int actual_length =
        std::vsnprintf(&str_[size], predicted_length + 1, fmt, args);
    RTC_DCHECK_GE(actual_length, 0);
  }
  va_end(args);
  return *this;
}

}  // namespace rtc
