// Copyright 2017 The Abseil 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.

#include "absl/strings/substitute.h"

#include <cstdint>
#include <vector>

#include "gtest/gtest.h"
#include "absl/strings/str_cat.h"

namespace {

TEST(SubstituteTest, Substitute) {
  // Basic.
  EXPECT_EQ("Hello, world!", absl::Substitute("$0, $1!", "Hello", "world"));

  // Non-char* types.
  EXPECT_EQ("123 0.2 0.1 foo true false x",
            absl::Substitute("$0 $1 $2 $3 $4 $5 $6", 123, 0.2, 0.1f,
                             std::string("foo"), true, false, 'x'));

  // All int types.
  EXPECT_EQ(
      "-32767 65535 "
      "-1234567890 3234567890 "
      "-1234567890 3234567890 "
      "-1234567890123456789 9234567890123456789",
      absl::Substitute(
          "$0 $1 $2 $3 $4 $5 $6 $7",
          static_cast<short>(-32767),          // NOLINT(runtime/int)
          static_cast<unsigned short>(65535),  // NOLINT(runtime/int)
          -1234567890, 3234567890U, -1234567890L, 3234567890UL,
          -int64_t{1234567890123456789}, uint64_t{9234567890123456789u}));

  // Hex format
  EXPECT_EQ("0 1 f ffff0ffff 0123456789abcdef",
            absl::Substitute("$0$1$2$3$4 $5",  //
                             absl::Hex(0), absl::Hex(1, absl::kSpacePad2),
                             absl::Hex(0xf, absl::kSpacePad2),
                             absl::Hex(int16_t{-1}, absl::kSpacePad5),
                             absl::Hex(int16_t{-1}, absl::kZeroPad5),
                             absl::Hex(0x123456789abcdef, absl::kZeroPad16)));

  // Dec format
  EXPECT_EQ("0 115   -1-0001 81985529216486895",
            absl::Substitute("$0$1$2$3$4 $5",  //
                             absl::Dec(0), absl::Dec(1, absl::kSpacePad2),
                             absl::Dec(0xf, absl::kSpacePad2),
                             absl::Dec(int16_t{-1}, absl::kSpacePad5),
                             absl::Dec(int16_t{-1}, absl::kZeroPad5),
                             absl::Dec(0x123456789abcdef, absl::kZeroPad16)));

  // Pointer.
  const int* int_p = reinterpret_cast<const int*>(0x12345);
  std::string str = absl::Substitute("$0", int_p);
  EXPECT_EQ(absl::StrCat("0x", absl::Hex(int_p)), str);

  // Volatile Pointer.
  // Like C++ streamed I/O, such pointers implicitly become bool
  volatile int vol = 237;
  volatile int *volatile volptr = &vol;
  str = absl::Substitute("$0", volptr);
  EXPECT_EQ("true", str);

  // null is special. StrCat prints 0x0. Substitute prints NULL.
  const uint64_t* null_p = nullptr;
  str = absl::Substitute("$0", null_p);
  EXPECT_EQ("NULL", str);

  // char* is also special.
  const char* char_p = "print me";
  str = absl::Substitute("$0", char_p);
  EXPECT_EQ("print me", str);

  char char_buf[16];
  strncpy(char_buf, "print me too", sizeof(char_buf));
  str = absl::Substitute("$0", char_buf);
  EXPECT_EQ("print me too", str);

  // null char* is "doubly" special. Represented as the empty std::string.
  char_p = nullptr;
  str = absl::Substitute("$0", char_p);
  EXPECT_EQ("", str);

  // Out-of-order.
  EXPECT_EQ("b, a, c, b", absl::Substitute("$1, $0, $2, $1", "a", "b", "c"));

  // Literal $
  EXPECT_EQ("$", absl::Substitute("$$"));

  EXPECT_EQ("$1", absl::Substitute("$$1"));

  // Test all overloads.
  EXPECT_EQ("a", absl::Substitute("$0", "a"));
  EXPECT_EQ("a b", absl::Substitute("$0 $1", "a", "b"));
  EXPECT_EQ("a b c", absl::Substitute("$0 $1 $2", "a", "b", "c"));
  EXPECT_EQ("a b c d", absl::Substitute("$0 $1 $2 $3", "a", "b", "c", "d"));
  EXPECT_EQ("a b c d e",
            absl::Substitute("$0 $1 $2 $3 $4", "a", "b", "c", "d", "e"));
  EXPECT_EQ("a b c d e f", absl::Substitute("$0 $1 $2 $3 $4 $5", "a", "b", "c",
                                            "d", "e", "f"));
  EXPECT_EQ("a b c d e f g", absl::Substitute("$0 $1 $2 $3 $4 $5 $6", "a", "b",
                                              "c", "d", "e", "f", "g"));
  EXPECT_EQ("a b c d e f g h",
            absl::Substitute("$0 $1 $2 $3 $4 $5 $6 $7", "a", "b", "c", "d", "e",
                             "f", "g", "h"));
  EXPECT_EQ("a b c d e f g h i",
            absl::Substitute("$0 $1 $2 $3 $4 $5 $6 $7 $8", "a", "b", "c", "d",
                             "e", "f", "g", "h", "i"));
  EXPECT_EQ("a b c d e f g h i j",
            absl::Substitute("$0 $1 $2 $3 $4 $5 $6 $7 $8 $9", "a", "b", "c",
                             "d", "e", "f", "g", "h", "i", "j"));
  EXPECT_EQ("a b c d e f g h i j b0",
            absl::Substitute("$0 $1 $2 $3 $4 $5 $6 $7 $8 $9 $10", "a", "b", "c",
                             "d", "e", "f", "g", "h", "i", "j"));

  const char* null_cstring = nullptr;
  EXPECT_EQ("Text: ''", absl::Substitute("Text: '$0'", null_cstring));
}

TEST(SubstituteTest, SubstituteAndAppend) {
  std::string str = "Hello";
  absl::SubstituteAndAppend(&str, ", $0!", "world");
  EXPECT_EQ("Hello, world!", str);

  // Test all overloads.
  str.clear();
  absl::SubstituteAndAppend(&str, "$0", "a");
  EXPECT_EQ("a", str);
  str.clear();
  absl::SubstituteAndAppend(&str, "$0 $1", "a", "b");
  EXPECT_EQ("a b", str);
  str.clear();
  absl::SubstituteAndAppend(&str, "$0 $1 $2", "a", "b", "c");
  EXPECT_EQ("a b c", str);
  str.clear();
  absl::SubstituteAndAppend(&str, "$0 $1 $2 $3", "a", "b", "c", "d");
  EXPECT_EQ("a b c d", str);
  str.clear();
  absl::SubstituteAndAppend(&str, "$0 $1 $2 $3 $4", "a", "b", "c", "d", "e");
  EXPECT_EQ("a b c d e", str);
  str.clear();
  absl::SubstituteAndAppend(&str, "$0 $1 $2 $3 $4 $5", "a", "b", "c", "d", "e",
                            "f");
  EXPECT_EQ("a b c d e f", str);
  str.clear();
  absl::SubstituteAndAppend(&str, "$0 $1 $2 $3 $4 $5 $6", "a", "b", "c", "d",
                            "e", "f", "g");
  EXPECT_EQ("a b c d e f g", str);
  str.clear();
  absl::SubstituteAndAppend(&str, "$0 $1 $2 $3 $4 $5 $6 $7", "a", "b", "c", "d",
                            "e", "f", "g", "h");
  EXPECT_EQ("a b c d e f g h", str);
  str.clear();
  absl::SubstituteAndAppend(&str, "$0 $1 $2 $3 $4 $5 $6 $7 $8", "a", "b", "c",
                            "d", "e", "f", "g", "h", "i");
  EXPECT_EQ("a b c d e f g h i", str);
  str.clear();
  absl::SubstituteAndAppend(&str, "$0 $1 $2 $3 $4 $5 $6 $7 $8 $9", "a", "b",
                            "c", "d", "e", "f", "g", "h", "i", "j");
  EXPECT_EQ("a b c d e f g h i j", str);
}

TEST(SubstituteTest, VectorBoolRef) {
  std::vector<bool> v = {true, false};
  const auto& cv = v;
  EXPECT_EQ("true false true false",
            absl::Substitute("$0 $1 $2 $3", v[0], v[1], cv[0], cv[1]));

  std::string str = "Logic be like: ";
  absl::SubstituteAndAppend(&str, "$0 $1 $2 $3", v[0], v[1], cv[0], cv[1]);
  EXPECT_EQ("Logic be like: true false true false", str);
}

#ifdef GTEST_HAS_DEATH_TEST

TEST(SubstituteDeathTest, SubstituteDeath) {
  EXPECT_DEBUG_DEATH(
      static_cast<void>(absl::Substitute(absl::string_view("-$2"), "a", "b")),
      "Invalid strings::Substitute\\(\\) format std::string: asked for \"\\$2\", "
      "but only 2 args were given.");
  EXPECT_DEBUG_DEATH(
      static_cast<void>(absl::Substitute("-$z-")),
      "Invalid strings::Substitute\\(\\) format std::string: \"-\\$z-\"");
  EXPECT_DEBUG_DEATH(
      static_cast<void>(absl::Substitute("-$")),
      "Invalid strings::Substitute\\(\\) format std::string: \"-\\$\"");
}

#endif  // GTEST_HAS_DEATH_TEST

}  // namespace
