/*
 *  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 <cstring>
#include <string>

#include "absl/strings/string_view.h"
#include "test/gmock.h"
#include "test/gtest.h"

namespace webrtc {
namespace {

class StructWithAbslStringify {
 public:
  explicit StructWithAbslStringify(absl::string_view sv) : value_(sv) {}

  template <typename Sink>
  friend void AbslStringify(Sink& sink, const StructWithAbslStringify& self) {
    sink.Append(self.value_);
  }

 private:
  std::string value_;
};

TEST(SimpleStringBuilder, Limit) {
  char sb_buf[10];
  SimpleStringBuilder sb(sb_buf);
  EXPECT_EQ(0u, strlen(sb.str()));

  // Test that for a SSB with a buffer size of 10, that we can write 9 chars
  // into it.
  sb << "012345678";  // 9 characters + '\0'.
  EXPECT_EQ(0, strcmp(sb.str(), "012345678"));
}

TEST(SimpleStringBuilder, NumbersAndChars) {
  char sb_buf[100];
  SimpleStringBuilder sb(sb_buf);
  sb << 1 << ':' << 2.1 << ":" << 2.2f << ':' << 78187493520ll << ':'
     << 78187493520ul;
  EXPECT_EQ(0, strcmp(sb.str(), "1:2.1:2.2:78187493520:78187493520"));
}

TEST(SimpleStringBuilder, Format) {
  char sb_buf[100];
  SimpleStringBuilder sb(sb_buf);
  sb << "Here we go - ";
  sb.AppendFormat("This is a hex formatted value: 0x%08llx", 3735928559ULL);
  EXPECT_EQ(0,
            strcmp(sb.str(),
                   "Here we go - This is a hex formatted value: 0xdeadbeef"));
}

TEST(SimpleStringBuilder, StdString) {
  char sb_buf[100];
  SimpleStringBuilder sb(sb_buf);
  std::string str = "does this work?";
  sb << str;
  EXPECT_EQ(str, sb.str());
}

TEST(SimpleStringBuilder, CanUseAbslStringForCustomTypes) {
  char sb_buf[100];
  SimpleStringBuilder sb(sb_buf);
  StructWithAbslStringify value("absl-stringify");
  sb << value;
  EXPECT_STREQ(sb.str(), "absl-stringify");
}

// These tests are safe to run if we have death test support or if DCHECKs are
// off.
#if GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)

TEST(SimpleStringBuilderDeathTest, BufferOverrunConstCharP) {
  char sb_buf[4];
  SimpleStringBuilder sb(sb_buf);
  const char* const msg = "This is just too much";
  EXPECT_DEATH(sb << msg, "");
}

TEST(SimpleStringBuilderDeathTest, BufferOverrunStdString) {
  char sb_buf[4];
  SimpleStringBuilder sb(sb_buf);
  sb << 12;
  const std::string msg = "Aw, come on!";
  EXPECT_DEATH(sb << msg, "");
}

TEST(SimpleStringBuilderDeathTest, BufferOverrunInt) {
  char sb_buf[4];
  SimpleStringBuilder sb(sb_buf);
  constexpr int num = -12345;
  EXPECT_DEATH(sb << num, "");
}

TEST(SimpleStringBuilderDeathTest, BufferOverrunDouble) {
  char sb_buf[5];
  SimpleStringBuilder sb(sb_buf);
  constexpr double num = 123.456;
  EXPECT_DEATH(sb << num, "");
}

TEST(SimpleStringBuilderDeathTest, BufferOverrunConstCharPAlreadyFull) {
  char sb_buf[4];
  SimpleStringBuilder sb(sb_buf);
  sb << 123;
  const char* const msg = "This is just too much";
  EXPECT_DEATH(sb << msg, "");
}

TEST(SimpleStringBuilderDeathTest, BufferOverrunIntAlreadyFull) {
  char sb_buf[4];
  SimpleStringBuilder sb(sb_buf);
  sb << "xyz";
  constexpr int num = -12345;
  EXPECT_DEATH(sb << num, "");
}

#endif

////////////////////////////////////////////////////////////////////////////////
// StringBuilder.

TEST(StringBuilder, Limit) {
  StringBuilder sb;
  EXPECT_EQ(0u, sb.str().size());

  sb << "012345678";
  EXPECT_EQ(sb.str(), "012345678");
}

TEST(StringBuilder, NumbersAndChars) {
  StringBuilder sb;
  sb << 1 << ":" << 2.1 << ":" << 2.2f << ":" << 78187493520ll << ":"
     << 78187493520ul;
  EXPECT_THAT(sb.str(),
              ::testing::MatchesRegex("1:2.10*:2.20*:78187493520:78187493520"));
}

TEST(StringBuilder, Format) {
  StringBuilder sb;
  sb << "Here we go - ";
  sb.AppendFormat("This is a hex formatted value: 0x%08llx", 3735928559ULL);
  EXPECT_EQ(sb.str(), "Here we go - This is a hex formatted value: 0xdeadbeef");
}

TEST(StringBuilder, StdString) {
  StringBuilder sb;
  std::string str = "does this work?";
  sb << str;
  EXPECT_EQ(str, sb.str());
}

TEST(StringBuilder, CanUseAbslStringForCustomTypes) {
  StringBuilder sb;
  StructWithAbslStringify value("absl-stringify");
  sb << value;
  EXPECT_EQ(sb.str(), "absl-stringify");
}

TEST(StringBuilder, Release) {
  StringBuilder sb;
  std::string str =
      "This string has to be of a moderate length, or we might "
      "run into problems with small object optimizations.";
  EXPECT_LT(sizeof(str), str.size());
  sb << str;
  EXPECT_EQ(str, sb.str());
  const char* original_buffer = sb.str().c_str();
  std::string moved = sb.Release();
  EXPECT_TRUE(sb.str().empty());
  EXPECT_EQ(str, moved);
  EXPECT_EQ(original_buffer, moved.c_str());
}

TEST(StringBuilder, Reset) {
  StringBuilder sb("abc");
  sb << "def";
  EXPECT_EQ("abcdef", sb.str());
  sb.Clear();
  EXPECT_TRUE(sb.str().empty());
  sb << 123 << "!";
  EXPECT_EQ("123!", sb.str());
}

}  // namespace
}  // namespace webrtc
