// Copyright (c) 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/third_party/quic/platform/api/quic_flags.h"

#include "base/optional.h"
#include "base/stl_util.h"
#include "base/strings/strcat.h"
#include "base/strings/string16.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "net/third_party/quic/platform/api/quic_logging.h"
#include "net/third_party/quic/platform/api/quic_string.h"
#include "net/third_party/quic/platform/api/quic_test.h"
#include "net/third_party/quic/platform/impl/quic_flags_impl.h"

DEFINE_QUIC_COMMAND_LINE_FLAG(bool, foo, false, "An old silent pond...");
DEFINE_QUIC_COMMAND_LINE_FLAG(int32_t, bar, 123, "A frog jumps into the pond,");
DEFINE_QUIC_COMMAND_LINE_FLAG(quic::QuicString,
                              baz,
                              "splash!",
                              "Silence again.");

namespace quic {
namespace test {

class QuicCommandLineFlagTest : public QuicTest {
 protected:
  void SetUp() override { QuicFlagRegistry::GetInstance().ResetFlags(); }

  static QuicParseCommandLineFlagsResult QuicParseCommandLineFlagsForTest(
      const char* usage,
      int argc,
      const char* const* argv) {
    base::CommandLine::StringVector v;
    FillCommandLineArgs(argc, argv, &v);
    return QuicParseCommandLineFlagsHelper(usage, base::CommandLine(v));
  }

 private:
  // Overload for platforms where base::CommandLine::StringType == std::string.
  static void FillCommandLineArgs(int argc,
                                  const char* const* argv,
                                  std::vector<std::string>* v) {
    for (int i = 0; i < argc; ++i) {
      v->push_back(argv[i]);
    }
  }

  // Overload for platforms where base::CommandLine::StringType ==
  // base::string16.
  static void FillCommandLineArgs(int argc,
                                  const char* const* argv,
                                  std::vector<base::string16>* v) {
    for (int i = 0; i < argc; ++i) {
      v->push_back(base::UTF8ToUTF16(argv[i]));
    }
  }
};

TEST_F(QuicCommandLineFlagTest, DefaultValues) {
  EXPECT_EQ(false, GetQuicFlag(FLAGS_foo));
  EXPECT_EQ(123, GetQuicFlag(FLAGS_bar));
  EXPECT_EQ("splash!", GetQuicFlag(FLAGS_baz));
}

TEST_F(QuicCommandLineFlagTest, NotSpecified) {
  const char* argv[]{"one", "two", "three"};
  auto parse_result =
      QuicParseCommandLineFlagsForTest("usage message", base::size(argv), argv);
  EXPECT_FALSE(parse_result.exit_status.has_value());
  std::vector<QuicString> expected_args{"two", "three"};
  EXPECT_EQ(expected_args, parse_result.non_flag_args);

  EXPECT_EQ(false, GetQuicFlag(FLAGS_foo));
  EXPECT_EQ(123, GetQuicFlag(FLAGS_bar));
  EXPECT_EQ("splash!", GetQuicFlag(FLAGS_baz));
}

TEST_F(QuicCommandLineFlagTest, BoolFlag) {
  for (const char* s :
       {"--foo", "--foo=1", "--foo=t", "--foo=True", "--foo=Y", "--foo=yes"}) {
    SetQuicFlag(&FLAGS_foo, false);
    const char* argv[]{"argv0", s};
    auto parse_result = QuicParseCommandLineFlagsForTest(
        "usage message", base::size(argv), argv);
    EXPECT_FALSE(parse_result.exit_status.has_value());
    EXPECT_TRUE(parse_result.non_flag_args.empty());
    EXPECT_TRUE(GetQuicFlag(FLAGS_foo));
  }

  for (const char* s :
       {"--foo=0", "--foo=f", "--foo=False", "--foo=N", "--foo=no"}) {
    SetQuicFlag(&FLAGS_foo, true);
    const char* argv[]{"argv0", s};
    auto parse_result = QuicParseCommandLineFlagsForTest(
        "usage message", base::size(argv), argv);
    EXPECT_FALSE(parse_result.exit_status.has_value());
    EXPECT_TRUE(parse_result.non_flag_args.empty());
    EXPECT_FALSE(GetQuicFlag(FLAGS_foo));
  }

  for (const char* s : {"--foo=7", "--foo=abc", "--foo=trueish"}) {
    SetQuicFlag(&FLAGS_foo, false);
    const char* argv[]{"argv0", s};

    testing::internal::CaptureStderr();
    auto parse_result = QuicParseCommandLineFlagsForTest(
        "usage message", base::size(argv), argv);
    std::string captured_stderr = testing::internal::GetCapturedStderr();

    EXPECT_TRUE(parse_result.exit_status.has_value());
    EXPECT_EQ(1, *parse_result.exit_status);
    EXPECT_THAT(captured_stderr,
                testing::ContainsRegex("Invalid value.*for flag --foo"));
    EXPECT_TRUE(parse_result.non_flag_args.empty());
    EXPECT_FALSE(GetQuicFlag(FLAGS_foo));
  }
}

TEST_F(QuicCommandLineFlagTest, Int32Flag) {
  for (const int i : {-1, 0, 100, 38239832}) {
    SetQuicFlag(&FLAGS_bar, 0);
    std::string flag_str = base::StringPrintf("--bar=%d", i);
    const char* argv[]{"argv0", flag_str.c_str()};
    auto parse_result = QuicParseCommandLineFlagsForTest(
        "usage message", base::size(argv), argv);
    EXPECT_FALSE(parse_result.exit_status.has_value());
    EXPECT_TRUE(parse_result.non_flag_args.empty());
    EXPECT_EQ(i, GetQuicFlag(FLAGS_bar));
  }

  for (const char* s : {"--bar", "--bar=a", "--bar=9999999999999"}) {
    SetQuicFlag(&FLAGS_bar, 0);
    const char* argv[]{"argv0", s};

    testing::internal::CaptureStderr();
    auto parse_result = QuicParseCommandLineFlagsForTest(
        "usage message", base::size(argv), argv);
    std::string captured_stderr = testing::internal::GetCapturedStderr();

    EXPECT_TRUE(parse_result.exit_status.has_value());
    EXPECT_EQ(1, *parse_result.exit_status);
    EXPECT_THAT(captured_stderr,
                testing::ContainsRegex("Invalid value.*for flag --bar"));
    EXPECT_TRUE(parse_result.non_flag_args.empty());
    EXPECT_EQ(0, GetQuicFlag(FLAGS_bar));
  }
}

TEST_F(QuicCommandLineFlagTest, StringFlag) {
  {
    SetQuicFlag(&FLAGS_baz, "whee");
    const char* argv[]{"argv0", "--baz"};
    auto parse_result = QuicParseCommandLineFlagsForTest(
        "usage message", base::size(argv), argv);
    EXPECT_FALSE(parse_result.exit_status.has_value());
    EXPECT_TRUE(parse_result.non_flag_args.empty());
    EXPECT_EQ("", GetQuicFlag(FLAGS_baz));
  }

  for (const char* s : {"", "12345", "abcdefg"}) {
    SetQuicFlag(&FLAGS_baz, "qux");
    std::string flag_str = base::StrCat({"--baz=", s});
    const char* argv[]{"argv0", flag_str.c_str()};
    auto parse_result = QuicParseCommandLineFlagsForTest(
        "usage message", base::size(argv), argv);
    EXPECT_FALSE(parse_result.exit_status.has_value());
    EXPECT_TRUE(parse_result.non_flag_args.empty());
    EXPECT_EQ(s, GetQuicFlag(FLAGS_baz));
  }
}

TEST_F(QuicCommandLineFlagTest, PrintHelp) {
  testing::internal::CaptureStdout();
  QuicPrintCommandLineFlagHelp("usage message");
  std::string captured_stdout = testing::internal::GetCapturedStdout();
  EXPECT_THAT(captured_stdout, testing::HasSubstr("usage message"));
  EXPECT_THAT(captured_stdout,
              testing::ContainsRegex("--help +Print this help message."));
  EXPECT_THAT(captured_stdout,
              testing::ContainsRegex("--foo +An old silent pond..."));
  EXPECT_THAT(captured_stdout,
              testing::ContainsRegex("--bar +A frog jumps into the pond,"));
  EXPECT_THAT(captured_stdout, testing::ContainsRegex("--baz +Silence again."));
}

}  // namespace test
}  // namespace quic
