// Copyright 2017-2020 The Verible 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
//
// 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 "common/util/subcommand.h"

#include <iostream>
#include <sstream>
#include <string>
#include <vector>

#include "absl/strings/match.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"

namespace verible {
namespace {

TEST(SubcommandRegistryTest, NoNewCommands) {
  SubcommandRegistry registry;
  const std::string command_list = registry.ListCommands();
  EXPECT_TRUE(absl::StrContains(command_list, "help"));
  // Make sure the internal 'error' command is not shown in help.
  EXPECT_FALSE(absl::StrContains(command_list, "error"));
}

TEST(SubcommandRegistryTest, HelpNoArgsTest) {
  SubcommandRegistry registry;
  // Test built-in help command.
  const SubcommandEntry& help(registry.GetSubcommandEntry("help"));
  std::istringstream ins;
  std::ostringstream outs, errs;
  std::vector<char*> args;
  const SubcommandArgsRange range(args.begin(), args.end());
  const auto status = help.main(range, ins, outs, errs);
  EXPECT_TRUE(status.ok()) << "Unexpected error:\n" << status.message();
  EXPECT_TRUE(outs.str().empty()) << outs.str();
  EXPECT_TRUE(absl::StrContains(errs.str(), "available commands:"));
}

TEST(SubcommandRegistryTest, HelpHelpCommand) {
  SubcommandRegistry registry;
  // Test built-in help command.
  const SubcommandEntry& help(registry.GetSubcommandEntry("help"));
  std::istringstream ins;
  std::ostringstream outs, errs;
  char arg[] = "help";
  std::vector<char*> args{arg};
  const SubcommandArgsRange range(args.begin(), args.end());

  const auto status = help.main(range, ins, outs, errs);
  EXPECT_TRUE(status.ok()) << "Unexpected error:\n" << status.message();
  EXPECT_TRUE(outs.str().empty()) << outs.str();
  EXPECT_TRUE(absl::StrContains(errs.str(), "Prints command help."));
}

static const SubcommandEntry fizz_func{
    [](const SubcommandArgsRange, std::istream&, std::ostream& outs,
       std::ostream&) {
      outs << 42;
      return absl::OkStatus();
    },
    "fizz does almost nothing",
    true,  // public
};

TEST(SubcommandRegistryTest, RegisterCommandPublicOk) {
  SubcommandRegistry registry;
  {
    const auto status = registry.RegisterCommand("fizz", fizz_func);
    EXPECT_TRUE(status.ok()) << "Unexpected error:\n" << status.message();
    EXPECT_TRUE(absl::StrContains(registry.ListCommands(), "fizz"));
  }

  std::vector<char*> args;
  const SubcommandArgsRange range(args.begin(), args.end());
  const SubcommandEntry& fizz_entry(registry.GetSubcommandEntry("fizz"));

  std::istringstream ins;
  std::ostringstream outs, errs;
  const auto status = fizz_entry.main(range, ins, outs, errs);
  EXPECT_TRUE(status.ok()) << "Unexpected error:\n" << status.message();
  EXPECT_EQ(outs.str(), "42");
}

static const SubcommandEntry buzz_func{
    [](const SubcommandArgsRange, std::istream&, std::ostream& outs,
       std::ostream&) {
      outs << 99;
      return absl::OkStatus();
    },
    "buzz does almost nothing",
    false,  // hidden
};

TEST(SubcommandRegistryTest, RegisterCommandHiddenOk) {
  SubcommandRegistry registry;
  {
    const auto status = registry.RegisterCommand("buzz", buzz_func);
    EXPECT_TRUE(status.ok()) << "Unexpected error:\n" << status.message();
    EXPECT_FALSE(absl::StrContains(registry.ListCommands(), "buzz"));
  }

  std::vector<char*> args;
  const SubcommandArgsRange range(args.begin(), args.end());
  const SubcommandEntry& buzz_entry(registry.GetSubcommandEntry("buzz"));

  std::istringstream ins;
  std::ostringstream outs, errs;
  const auto status = buzz_entry.main(range, ins, outs, errs);
  EXPECT_TRUE(status.ok()) << "Unexpected error:\n" << status.message();
  EXPECT_EQ(outs.str(), "99");
}

TEST(SubcommandRegistryTest, RegisterCommandErrorAlreadyRegistered) {
  SubcommandRegistry registry;
  // "help" is already a registered command
  const auto status = registry.RegisterCommand("help", fizz_func);
  EXPECT_FALSE(status.ok());
  EXPECT_TRUE(
      absl::StrContains(status.message(), "has already been registered"));
}

TEST(SubcommandRegistryTest, RegisterCommandMultipleCommands) {
  SubcommandRegistry registry;
  {
    {
      const auto status = registry.RegisterCommand("buzz", buzz_func);
      EXPECT_TRUE(status.ok()) << "Unexpected error:\n" << status.message();
    }
    {
      const auto status = registry.RegisterCommand("fizz", fizz_func);
      EXPECT_TRUE(status.ok()) << "Unexpected error:\n" << status.message();
    }
    const std::string command_list = registry.ListCommands();
    EXPECT_TRUE(absl::StrContains(command_list, "fizz"));
    EXPECT_FALSE(absl::StrContains(command_list, "buzz"));
  }

  // Run each subcommand once.
  std::vector<char*> args;
  const SubcommandArgsRange range(args.begin(), args.end());
  {
    const SubcommandEntry& fizz_entry(registry.GetSubcommandEntry("fizz"));
    std::istringstream ins;
    std::ostringstream outs, errs;
    const auto status = fizz_entry.main(range, ins, outs, errs);
    EXPECT_TRUE(status.ok()) << "Unexpected error:\n" << status.message();
    EXPECT_EQ(outs.str(), "42");
  }
  {
    const SubcommandEntry& buzz_entry(registry.GetSubcommandEntry("buzz"));
    std::istringstream ins;
    std::ostringstream outs, errs;
    const auto status = buzz_entry.main(range, ins, outs, errs);
    EXPECT_TRUE(status.ok()) << "Unexpected error:\n" << status.message();
    EXPECT_EQ(outs.str(), "99");
  }
}

}  // namespace
}  // namespace verible
