// Copyright 2017 The Bazel Authors. All rights reserved.
//
// 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 "src/main/cpp/option_processor.h"

#include "src/main/cpp/bazel_startup_options.h"
#include "src/main/cpp/blaze_util.h"
#include "src/main/cpp/blaze_util_platform.h"
#include "src/main/cpp/option_processor-internal.h"
#include "src/main/cpp/util/file.h"
#include "src/main/cpp/util/file_platform.h"
#include "src/main/cpp/util/path.h"
#include "src/main/cpp/workspace_layout.h"
#include "googletest/include/gtest/gtest.h"

namespace blaze {

class OptionProcessorTest : public ::testing::Test {
 protected:
  OptionProcessorTest()
      : workspace_(
            blaze_util::JoinPath(blaze::GetPathEnv("TEST_TMPDIR"), "testdir")),
        cwd_("cwd"),
        workspace_layout_(new WorkspaceLayout()) {}

  ~OptionProcessorTest() override {}

  void SetUp() override {
    ASSERT_TRUE(blaze_util::MakeDirectories(workspace_, 0755));
    option_processor_.reset(new OptionProcessor(
        workspace_layout_.get(),
        std::unique_ptr<StartupOptions>(
            new BazelStartupOptions(workspace_layout_.get()))));
  }

  void TearDown() override {
    // TODO(bazel-team): The code below deletes all the files in the workspace
    // but it intentionally skips directories. As a consequence, there may be
    // empty directories from test to test. Remove this once
    // blaze_util::DeleteDirectories(path) exists.
    std::vector<std::string> files_in_workspace;
    blaze_util::GetAllFilesUnder(workspace_, &files_in_workspace);
    for (const std::string& file : files_in_workspace) {
      blaze_util::UnlinkPath(file);
    }
  }

  void FailedSplitStartupOptionsTest(const std::vector<std::string>& args,
                                     const std::string& expected_error) const {
    std::string error;
    const std::unique_ptr<CommandLine> result =
        option_processor_->SplitCommandLine(args, &error);
    ASSERT_EQ(expected_error, error);
    ASSERT_EQ(nullptr, result);
  }

  void SuccessfulSplitStartupOptionsTest(const std::vector<std::string>& args,
                                         const CommandLine& expected) const {
    std::string error;
    const std::unique_ptr<CommandLine> result =
        option_processor_->SplitCommandLine(args, &error);

    ASSERT_EQ("", error);
    EXPECT_EQ(expected.path_to_binary, result->path_to_binary);
    EXPECT_EQ(expected.startup_args, result->startup_args);
    EXPECT_EQ(expected.command, result->command);
    EXPECT_EQ(expected.command_args, result->command_args);
  }

  void HelpArgIsInterpretedAsACommand(const std::string& arg) {
    const std::vector<std::string> args = {"bazel", arg};
    std::string error;
    ASSERT_EQ(blaze_exit_code::SUCCESS,
              option_processor_->ParseOptions(args, workspace_, cwd_, &error))
        << error;
    ASSERT_EQ("", error);

    EXPECT_EQ(arg, option_processor_->GetCommand());
    EXPECT_EQ(std::vector<std::string>({}),
              option_processor_->GetExplicitCommandArguments());
  }

  const std::string workspace_;
  const std::string cwd_;
  const std::unique_ptr<WorkspaceLayout> workspace_layout_;
  std::unique_ptr<OptionProcessor> option_processor_;
};

TEST_F(OptionProcessorTest, CanParseOptions) {
  const std::vector<std::string> args = {"bazel",     "--host_jvm_args=MyParam",
                                         "--nobatch", "command",
                                         "--flag",    "//my:target",
                                         "--flag2=42"};
  std::string error;
  ASSERT_EQ(blaze_exit_code::SUCCESS,
            option_processor_->ParseOptions(args, workspace_, cwd_, &error))
      << error;

  ASSERT_EQ("", error);
#if defined(_WIN32) || defined(__CYGWIN__)
  ASSERT_EQ(size_t(2),
            option_processor_->GetParsedStartupOptions()->host_jvm_args.size());
  const std::string win_unix_root("-Dbazel.windows_unix_root=");
  const std::string host_jvm_args_0 =
      option_processor_->GetParsedStartupOptions()->host_jvm_args[0];
  EXPECT_EQ(host_jvm_args_0.find(win_unix_root), 0) << host_jvm_args_0;
  EXPECT_GT(host_jvm_args_0.size(), win_unix_root.size());
  EXPECT_EQ("MyParam",
            option_processor_->GetParsedStartupOptions()->host_jvm_args[1]);
#else   // ! (defined(_WIN32) || defined(__CYGWIN__))
  ASSERT_EQ(size_t(1),
            option_processor_->GetParsedStartupOptions()->host_jvm_args.size());
  EXPECT_EQ("MyParam",
            option_processor_->GetParsedStartupOptions()->host_jvm_args[0]);
#endif  // defined(_WIN32) || defined(__CYGWIN__)
  EXPECT_FALSE(option_processor_->GetParsedStartupOptions()->batch);

  EXPECT_EQ("command", option_processor_->GetCommand());

  EXPECT_EQ(std::vector<std::string>({"--flag", "//my:target", "--flag2=42"}),
            option_processor_->GetExplicitCommandArguments());
}

TEST_F(OptionProcessorTest, CanParseHelpCommandSurroundedByOtherArgs) {
  const std::vector<std::string> args = {"bazel",     "--host_jvm_args=MyParam",
                                         "--nobatch", "help",
                                         "--flag",    "//my:target",
                                         "--flag2=42"};
  std::string error;
  ASSERT_EQ(blaze_exit_code::SUCCESS,
            option_processor_->ParseOptions(args, workspace_, cwd_, &error))
      << error;

  ASSERT_EQ("", error);
#if defined(_WIN32) || defined(__CYGWIN__)
  ASSERT_EQ(size_t(2),
            option_processor_->GetParsedStartupOptions()->host_jvm_args.size());
  const std::string win_unix_root("-Dbazel.windows_unix_root=");
  const std::string host_jvm_args_0 =
      option_processor_->GetParsedStartupOptions()->host_jvm_args[0];
  EXPECT_EQ(host_jvm_args_0.find(win_unix_root), 0) << host_jvm_args_0;
  EXPECT_GT(host_jvm_args_0.size(), win_unix_root.size());
  EXPECT_EQ("MyParam",
            option_processor_->GetParsedStartupOptions()->host_jvm_args[1]);
#else   // ! (defined(_WIN32) || defined(__CYGWIN__))
  ASSERT_EQ(size_t(1),
            option_processor_->GetParsedStartupOptions()->host_jvm_args.size());
  EXPECT_EQ("MyParam",
            option_processor_->GetParsedStartupOptions()->host_jvm_args[0]);
#endif  // defined(_WIN32) || defined(__CYGWIN__)
  EXPECT_FALSE(option_processor_->GetParsedStartupOptions()->batch);

  EXPECT_EQ("help", option_processor_->GetCommand());

  EXPECT_EQ(std::vector<std::string>({"--flag", "//my:target", "--flag2=42"}),
            option_processor_->GetExplicitCommandArguments());
}

TEST_F(OptionProcessorTest, CanParseHelpCommand) {
  HelpArgIsInterpretedAsACommand("help");
}

TEST_F(OptionProcessorTest, CanParseHelpShortFlag) {
  HelpArgIsInterpretedAsACommand("-h");
}

TEST_F(OptionProcessorTest, CanParseHelpFlag) {
  HelpArgIsInterpretedAsACommand("-help");
}

TEST_F(OptionProcessorTest, CanParseEmptyArgs) {
  const std::vector<std::string> args = {"bazel"};
  std::string error;
  ASSERT_EQ(blaze_exit_code::SUCCESS,
            option_processor_->ParseOptions(args, workspace_, cwd_, &error))
                << error;
  ASSERT_EQ("", error);

  EXPECT_EQ("", option_processor_->GetCommand());

  EXPECT_EQ(std::vector<std::string>({}),
            option_processor_->GetExplicitCommandArguments());
}

TEST_F(OptionProcessorTest, CanParseDifferentStartupArgs) {
  const std::vector<std::string> args =
      {"bazel",
       "--nobatch", "--host_jvm_args=MyParam", "--host_jvm_args", "42"};
  std::string error;
  ASSERT_EQ(blaze_exit_code::SUCCESS,
            option_processor_->ParseOptions(args, workspace_, cwd_, &error))
                << error;
  ASSERT_EQ("", error);

#if defined(_WIN32) || defined(__CYGWIN__)
  ASSERT_EQ(size_t(3),
            option_processor_->GetParsedStartupOptions()->host_jvm_args.size());
  const std::string win_unix_root("-Dbazel.windows_unix_root=");
  const std::string host_jvm_args_0 =
      option_processor_->GetParsedStartupOptions()->host_jvm_args[0];
  EXPECT_EQ(host_jvm_args_0.find(win_unix_root), 0) << host_jvm_args_0;
  EXPECT_GT(host_jvm_args_0.size(), win_unix_root.size());
  EXPECT_EQ("MyParam",
            option_processor_->GetParsedStartupOptions()->host_jvm_args[1]);
  EXPECT_EQ("42",
            option_processor_->GetParsedStartupOptions()->host_jvm_args[2]);
#else   // ! (defined(_WIN32) || defined(__CYGWIN__))
  ASSERT_EQ(size_t(2),
            option_processor_->GetParsedStartupOptions()->host_jvm_args.size());
  EXPECT_EQ("MyParam",
            option_processor_->GetParsedStartupOptions()->host_jvm_args[0]);
  EXPECT_EQ("42",
            option_processor_->GetParsedStartupOptions()->host_jvm_args[1]);
#endif  // defined(_WIN32) || defined(__CYGWIN__)

  EXPECT_EQ("", option_processor_->GetCommand());

  EXPECT_EQ(std::vector<std::string>({}),
            option_processor_->GetExplicitCommandArguments());
}

TEST_F(OptionProcessorTest, SplitCommandLineWithEmptyArgs) {
  FailedSplitStartupOptionsTest(
      {},
      "Unable to split command line, args is empty");
}

TEST_F(OptionProcessorTest, SplitCommandLineWithAllParams) {
  SuccessfulSplitStartupOptionsTest(
      {"bazel", "--nomaster_bazelrc", "build", "--bar", ":mytarget"},
      CommandLine("bazel",
                  {"--nomaster_bazelrc"},
                  "build",
                  {"--bar", ":mytarget"}));
}

TEST_F(OptionProcessorTest, SplitCommandLineWithAbsolutePathToBinary) {
  SuccessfulSplitStartupOptionsTest(
      {"mybazel", "build", ":mytarget"},
      CommandLine("mybazel", {}, "build", {":mytarget"}));
}

TEST_F(OptionProcessorTest, SplitCommandLineWithUnaryStartupWithEquals) {
  SuccessfulSplitStartupOptionsTest(
      {"bazel", "--bazelrc=foo", "build", ":mytarget"},
      CommandLine("bazel", {"--bazelrc=foo"}, "build", {":mytarget"}));
}

TEST_F(OptionProcessorTest,
       SplitCommandLineWithUnaryStartupWithoutEquals) {
  SuccessfulSplitStartupOptionsTest(
      {"bazel", "--bazelrc", "foo", "build", ":mytarget"},
      CommandLine("bazel", {"--bazelrc=foo"}, "build", {":mytarget"}));
}

TEST_F(OptionProcessorTest, SplitCommandLineWithIncompleteUnaryOption) {
  FailedSplitStartupOptionsTest(
      {"bazel", "--bazelrc"},
      "Startup option '--bazelrc' expects a value.\n"
          "Usage: '--bazelrc=somevalue' or '--bazelrc somevalue'.\n"
          "  For more info, run 'bazel help startup_options'.");
}

TEST_F(OptionProcessorTest, SplitCommandLineWithMultipleStartup) {
  SuccessfulSplitStartupOptionsTest(
      {"bazel", "--bazelrc", "foo", "--nomaster_bazelrc", "build", ":mytarget"},
      CommandLine("bazel",
                  {"--bazelrc=foo", "--nomaster_bazelrc"},
                  "build",
                  {":mytarget"}));
}

TEST_F(OptionProcessorTest, SplitCommandLineWithNoStartupArgs) {
  SuccessfulSplitStartupOptionsTest(
      {"bazel", "build", ":mytarget"},
      CommandLine("bazel", {}, "build", {":mytarget"}));
}

TEST_F(OptionProcessorTest, SplitCommandLineWithNoCommandArgs) {
  SuccessfulSplitStartupOptionsTest(
      {"bazel", "build"},
      CommandLine("bazel", {}, "build", {}));
}

TEST_F(OptionProcessorTest, SplitCommandLineWithBlazeHelp) {
  SuccessfulSplitStartupOptionsTest(
      {"bazel", "help"},
      CommandLine("bazel", {}, "help", {}));

  SuccessfulSplitStartupOptionsTest(
      {"bazel", "-h"},
      CommandLine("bazel", {}, "-h", {}));

  SuccessfulSplitStartupOptionsTest(
      {"bazel", "-help"},
      CommandLine("bazel", {}, "-help", {}));

  SuccessfulSplitStartupOptionsTest(
      {"bazel", "--help"},
      CommandLine("bazel", {}, "--help", {}));
}

TEST_F(OptionProcessorTest, SplitCommandLineWithBlazeVersion) {
  SuccessfulSplitStartupOptionsTest(
      {"bazel", "version"},
      CommandLine("bazel", {}, "version", {}));
}

TEST_F(OptionProcessorTest, SplitCommandLineWithMultipleCommandArgs) {
  SuccessfulSplitStartupOptionsTest(
      {"bazel", "build", "--foo", "-s", ":mytarget"},
      CommandLine("bazel", {}, "build", {"--foo", "-s", ":mytarget"}));
}

TEST_F(OptionProcessorTest,
       SplitCommandLineFailsWithDashDashInStartupArgs) {
  FailedSplitStartupOptionsTest(
      {"bazel", "--"},
      "Unknown startup option: '--'.\n"
          "  For more info, run 'bazel help startup_options'.");
}

TEST_F(OptionProcessorTest, SplitCommandLineWithDashDash) {
  SuccessfulSplitStartupOptionsTest(
      {"bazel", "--nomaster_bazelrc", "build", "--b", "--", ":mytarget"},
      CommandLine("bazel",
                  {"--nomaster_bazelrc"},
                  "build",
                  {"--b", "--", ":mytarget"}));
}

TEST_F(OptionProcessorTest, TestDedupePathsOmitsInvalidPath) {
  std::vector<std::string> input = {"foo"};
  std::vector<std::string> expected = {};
  ASSERT_EQ(expected, internal::DedupeBlazercPaths(input));
}

TEST_F(OptionProcessorTest, TestDedupePathsOmitsEmptyPath) {
  std::vector<std::string> input = {""};
  std::vector<std::string> expected = {};
  ASSERT_EQ(expected, internal::DedupeBlazercPaths(input));
}

TEST_F(OptionProcessorTest, TestDedupePathsWithDifferentFiles) {
  std::string foo_path = blaze_util::JoinPath(workspace_, "foo");
  std::string bar_path = blaze_util::JoinPath(workspace_, "bar");

  ASSERT_TRUE(blaze_util::WriteFile("foo", foo_path));
  ASSERT_TRUE(blaze_util::WriteFile("bar", bar_path));

  std::vector<std::string> input = {foo_path, bar_path};
  ASSERT_EQ(input, internal::DedupeBlazercPaths(input));
}

TEST_F(OptionProcessorTest, TestDedupePathsWithSameFile) {
  std::string foo_path = blaze_util::JoinPath(workspace_, "foo");

  ASSERT_TRUE(blaze_util::WriteFile("foo", foo_path));

  std::vector<std::string> input = {foo_path, foo_path};
  std::vector<std::string> expected = {foo_path};
  ASSERT_EQ(expected, internal::DedupeBlazercPaths(input));
}

TEST_F(OptionProcessorTest, TestDedupePathsWithRelativePath) {
  std::string dir(blaze_util::JoinPath(workspace_, "dir"));
  std::string foo_path(blaze_util::JoinPath(dir, "foo"));
  std::string relative_foo_path(blaze_util::JoinPath(dir, "../dir/foo"));

  ASSERT_TRUE(blaze_util::MakeDirectories(dir, 0755));
  ASSERT_TRUE(blaze_util::WriteFile("foo", foo_path));

  std::vector<std::string> input = {foo_path, relative_foo_path};
  std::vector<std::string> expected = {foo_path};
  ASSERT_EQ(expected, internal::DedupeBlazercPaths(input));
}

#if !defined(_WIN32) && !defined(__CYGWIN__)
static bool Symlink(const std::string& old_path, const std::string& new_path) {
  return symlink(old_path.c_str(), new_path.c_str()) == 0;
}

TEST_F(OptionProcessorTest, TestDedupePathsWithSymbolicLink) {
  std::string foo_path = blaze_util::JoinPath(workspace_, "foo");
  std::string sym_foo_path = blaze_util::JoinPath(workspace_, "sym_foo");

  ASSERT_TRUE(blaze_util::WriteFile("foo", foo_path));
  ASSERT_TRUE(Symlink(foo_path, sym_foo_path));
  std::vector<std::string> input = {foo_path, sym_foo_path};
  std::vector<std::string> expected = {foo_path};
  ASSERT_EQ(expected, internal::DedupeBlazercPaths(input));
}
#endif  // !defined(_WIN32) && !defined(__CYGWIN__)

}  // namespace blaze
