// 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
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
#include "absl/strings/internal/str_format/arg.h"

#include <ostream>
#include <string>
#include "gtest/gtest.h"
#include "absl/strings/str_format.h"

namespace absl {
namespace str_format_internal {
namespace {

class FormatArgImplTest : public ::testing::Test {
 public:
  enum Color { kRed, kGreen, kBlue };

  static const char *hi() { return "hi"; }
};

TEST_F(FormatArgImplTest, ToInt) {
  int out = 0;
  EXPECT_TRUE(FormatArgImplFriend::ToInt(FormatArgImpl(1), &out));
  EXPECT_EQ(1, out);
  EXPECT_TRUE(FormatArgImplFriend::ToInt(FormatArgImpl(-1), &out));
  EXPECT_EQ(-1, out);
  EXPECT_TRUE(
      FormatArgImplFriend::ToInt(FormatArgImpl(static_cast<char>(64)), &out));
  EXPECT_EQ(64, out);
  EXPECT_TRUE(FormatArgImplFriend::ToInt(
      FormatArgImpl(static_cast<unsigned long long>(123456)), &out));  // NOLINT
  EXPECT_EQ(123456, out);
  EXPECT_TRUE(FormatArgImplFriend::ToInt(
      FormatArgImpl(static_cast<unsigned long long>(  // NOLINT
                        std::numeric_limits<int>::max()) +
                    1),
      &out));
  EXPECT_EQ(std::numeric_limits<int>::max(), out);
  EXPECT_TRUE(FormatArgImplFriend::ToInt(
      FormatArgImpl(static_cast<long long>(  // NOLINT
                        std::numeric_limits<int>::min()) -
                    10),
      &out));
  EXPECT_EQ(std::numeric_limits<int>::min(), out);
  EXPECT_TRUE(FormatArgImplFriend::ToInt(FormatArgImpl(false), &out));
  EXPECT_EQ(0, out);
  EXPECT_TRUE(FormatArgImplFriend::ToInt(FormatArgImpl(true), &out));
  EXPECT_EQ(1, out);
  EXPECT_FALSE(FormatArgImplFriend::ToInt(FormatArgImpl(2.2), &out));
  EXPECT_FALSE(FormatArgImplFriend::ToInt(FormatArgImpl(3.2f), &out));
  EXPECT_FALSE(FormatArgImplFriend::ToInt(
      FormatArgImpl(static_cast<int *>(nullptr)), &out));
  EXPECT_FALSE(FormatArgImplFriend::ToInt(FormatArgImpl(hi()), &out));
  EXPECT_FALSE(FormatArgImplFriend::ToInt(FormatArgImpl("hi"), &out));
  EXPECT_TRUE(FormatArgImplFriend::ToInt(FormatArgImpl(kBlue), &out));
  EXPECT_EQ(2, out);
}

extern const char kMyArray[];

TEST_F(FormatArgImplTest, CharArraysDecayToCharPtr) {
  const char* a = "";
  EXPECT_EQ(FormatArgImplFriend::GetVTablePtrForTest(FormatArgImpl(a)),
            FormatArgImplFriend::GetVTablePtrForTest(FormatArgImpl("")));
  EXPECT_EQ(FormatArgImplFriend::GetVTablePtrForTest(FormatArgImpl(a)),
            FormatArgImplFriend::GetVTablePtrForTest(FormatArgImpl("A")));
  EXPECT_EQ(FormatArgImplFriend::GetVTablePtrForTest(FormatArgImpl(a)),
            FormatArgImplFriend::GetVTablePtrForTest(FormatArgImpl("ABC")));
  EXPECT_EQ(FormatArgImplFriend::GetVTablePtrForTest(FormatArgImpl(a)),
            FormatArgImplFriend::GetVTablePtrForTest(FormatArgImpl(kMyArray)));
}

TEST_F(FormatArgImplTest, OtherPtrDecayToVoidPtr) {
  auto expected = FormatArgImplFriend::GetVTablePtrForTest(
      FormatArgImpl(static_cast<void *>(nullptr)));
  EXPECT_EQ(FormatArgImplFriend::GetVTablePtrForTest(
                FormatArgImpl(static_cast<int *>(nullptr))),
            expected);
  EXPECT_EQ(FormatArgImplFriend::GetVTablePtrForTest(
                FormatArgImpl(static_cast<volatile int *>(nullptr))),
            expected);

  auto p = static_cast<void (*)()>([] {});
  EXPECT_EQ(FormatArgImplFriend::GetVTablePtrForTest(FormatArgImpl(p)),
            expected);
}

TEST_F(FormatArgImplTest, WorksWithCharArraysOfUnknownSize) {
  std::string s;
  FormatSinkImpl sink(&s);
  ConversionSpec conv;
  conv.set_conv(ConversionChar::FromChar('s'));
  conv.set_flags(Flags());
  conv.set_width(-1);
  conv.set_precision(-1);
  EXPECT_TRUE(
      FormatArgImplFriend::Convert(FormatArgImpl(kMyArray), conv, &sink));
  sink.Flush();
  EXPECT_EQ("ABCDE", s);
}
const char kMyArray[] = "ABCDE";

}  // namespace
}  // namespace str_format_internal
}  // namespace absl
