/*
 * Copyright (C) 2015, The Android Open Source Project
 *
 * 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 "options.h"

#include <iostream>
#include <memory>
#include <string>
#include <vector>

#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include "diagnostics.h"

using android::aidl::DiagnosticID;
using android::aidl::DiagnosticSeverity;
using std::cerr;
using std::endl;
using std::string;
using std::unique_ptr;
using std::vector;
using testing::internal::CaptureStderr;
using testing::internal::GetCapturedStderr;

namespace android {
namespace aidl {
namespace {

const char kPreprocessCommandOutputFile[] = "output_file_name";
const char kPreprocessCommandInput1[] = "input1.aidl";
const char kPreprocessCommandInput2[] = "input2.aidl";
const char kPreprocessCommandInput3[] = "input3.aidl";
const char* kPreprocessCommand[] = {
    "aidl", "--preprocess",
    kPreprocessCommandOutputFile,
    kPreprocessCommandInput1,
    kPreprocessCommandInput2,
    kPreprocessCommandInput3,
    nullptr,
};

const char kCompileCommandInput[] = "directory/ITool.aidl";
const char kCompileCommandIncludePath[] = "-Iinclude_path";
const char* kCompileJavaCommand[] = {
    "aidl",
    "-b",
    kCompileCommandIncludePath,
    kCompileCommandInput,
    nullptr,
};
const char kCompileCommandJavaOutput[] = "directory/ITool.java";

const char kCompileDepFileNinja[] = "--ninja";
const char* kCompileJavaCommandNinja[] = {
    "aidl",
    "-b",
    kCompileDepFileNinja,
    kCompileCommandIncludePath,
    kCompileCommandInput,
    nullptr,
};

const char kCompileDepFile[] = "-doutput.deps";
const char kCompileCommandHeaderDir[] = "output/dir/";
const char kCompileCommandCppOutput[] = "some/file.cpp";
const char* kCompileCppCommand[] = {
    "aidl-cpp",
    kCompileCommandIncludePath,
    kCompileDepFile,
    kCompileCommandInput,
    kCompileCommandHeaderDir,
    kCompileCommandCppOutput,
    nullptr,
};
const char* kCompileCppCommandNinja[] = {
    "aidl-cpp",
    kCompileCommandIncludePath,
    kCompileDepFile,
    kCompileDepFileNinja,
    kCompileCommandInput,
    kCompileCommandHeaderDir,
    kCompileCommandCppOutput,
    nullptr,
};

unique_ptr<Options> GetOptions(const char* command[],
                               Options::Language default_lang = Options::Language::JAVA) {
  int argc = 0;
  const char** command_part = command;
  for (; *command_part; ++argc, ++command_part) {}
  unique_ptr<Options> ret(new Options(argc, command, default_lang));
  if (!ret->Ok()) {
    cerr << ret->GetErrorMessage();
    cerr << "Failed to parse command line:";
    for (int i = 0; i < argc; ++i) {
      cerr << " " << command[i];
      cerr << endl;
    }
  }
  EXPECT_NE(ret, nullptr) << "Failed to parse options!";
  return ret;
}

}  // namespace

TEST(OptionsTests, ParsesPreprocess) {
  unique_ptr<Options> options = GetOptions(kPreprocessCommand);
  EXPECT_EQ(Options::Task::PREPROCESS, options->GetTask());
  EXPECT_EQ(false, options->FailOnParcelable());
  EXPECT_EQ(0u, options->ImportDirs().size());
  EXPECT_EQ(0u, options->PreprocessedFiles().size());
  EXPECT_EQ(string{kPreprocessCommandOutputFile}, options->OutputFile());
  EXPECT_EQ(false, options->AutoDepFile());
  const vector<string> expected_input{kPreprocessCommandInput1,
                                      kPreprocessCommandInput2,
                                      kPreprocessCommandInput3};
  EXPECT_EQ(expected_input, options->InputFiles());
}

TEST(OptionsTests, ParsesCompileJava) {
  unique_ptr<Options> options = GetOptions(kCompileJavaCommand);
  EXPECT_EQ(Options::Task::COMPILE, options->GetTask());
  EXPECT_EQ(Options::Language::JAVA, options->TargetLanguage());
  EXPECT_EQ(true, options->FailOnParcelable());
  EXPECT_EQ(1u, options->ImportDirs().size());
  EXPECT_EQ(0u, options->PreprocessedFiles().size());
  EXPECT_EQ(string{kCompileCommandInput}, options->InputFiles().front());
  EXPECT_EQ(string{kCompileCommandJavaOutput}, options->OutputFile());
  EXPECT_EQ(false, options->AutoDepFile());
  EXPECT_EQ(false, options->DependencyFileNinja());
}

TEST(OptionsTests, ParsesCompileJavaNinja) {
  unique_ptr<Options> options = GetOptions(kCompileJavaCommandNinja);
  EXPECT_EQ(Options::Task::COMPILE, options->GetTask());
  EXPECT_EQ(Options::Language::JAVA, options->TargetLanguage());
  EXPECT_EQ(true, options->FailOnParcelable());
  EXPECT_EQ(1u, options->ImportDirs().size());
  EXPECT_EQ(0u, options->PreprocessedFiles().size());
  EXPECT_EQ(string{kCompileCommandInput}, options->InputFiles().front());
  EXPECT_EQ(string{kCompileCommandJavaOutput}, options->OutputFile());
  EXPECT_EQ(false, options->AutoDepFile());
  EXPECT_EQ(true, options->DependencyFileNinja());
}

TEST(OptionsTests, ParsesCompileCpp) {
  unique_ptr<Options> options = GetOptions(kCompileCppCommand, Options::Language::CPP);
  ASSERT_EQ(1u, options->ImportDirs().size());
  EXPECT_EQ(string{kCompileCommandIncludePath}.substr(2), *options->ImportDirs().begin());
  EXPECT_EQ(string{kCompileDepFile}.substr(2), options->DependencyFile());
  EXPECT_EQ(false, options->DependencyFileNinja());
  EXPECT_EQ(kCompileCommandInput, options->InputFiles().front());
  EXPECT_EQ(kCompileCommandHeaderDir, options->OutputHeaderDir());
  EXPECT_EQ(kCompileCommandCppOutput, options->OutputFile());
}

TEST(OptionsTests, ParsesCompileCppNinja) {
  unique_ptr<Options> options = GetOptions(kCompileCppCommandNinja, Options::Language::CPP);
  ASSERT_EQ(1u, options->ImportDirs().size());
  EXPECT_EQ(string{kCompileCommandIncludePath}.substr(2), *options->ImportDirs().begin());
  EXPECT_EQ(string{kCompileDepFile}.substr(2), options->DependencyFile());
  EXPECT_EQ(true, options->DependencyFileNinja());
  EXPECT_EQ(kCompileCommandInput, options->InputFiles().front());
  EXPECT_EQ(kCompileCommandHeaderDir, options->OutputHeaderDir());
  EXPECT_EQ(kCompileCommandCppOutput, options->OutputFile());
}

TEST(OptionsTests, ParsesCompileJavaMultiInput) {
  const char* argv[] = {
      "aidl",
      "--lang=java",
      kCompileCommandIncludePath,
      "-o src_out",
      "directory/input1.aidl",
      "directory/input2.aidl",
      "directory/input3.aidl",
      nullptr,
  };
  unique_ptr<Options> options = GetOptions(argv);
  EXPECT_EQ(Options::Task::COMPILE, options->GetTask());
  EXPECT_EQ(Options::Language::JAVA, options->TargetLanguage());
  EXPECT_EQ(false, options->FailOnParcelable());
  EXPECT_EQ(1u, options->ImportDirs().size());
  EXPECT_EQ(0u, options->PreprocessedFiles().size());
  const vector<string> expected_input{"directory/input1.aidl", "directory/input2.aidl",
                                      "directory/input3.aidl"};
  EXPECT_EQ(expected_input, options->InputFiles());
  EXPECT_EQ(string{""}, options->OutputFile());
  EXPECT_EQ(false, options->AutoDepFile());
  EXPECT_EQ(false, options->DependencyFileNinja());
  EXPECT_EQ(string{""}, options->OutputHeaderDir());
  EXPECT_EQ(string{"src_out/"}, options->OutputDir());
}

TEST(OptionsTests, ParsesCompileRust) {
  const char* argv[] = {
      "aidl",       "--lang=rust",        kCompileCommandIncludePath,
      "-o src_out", kCompileCommandInput, nullptr,
  };
  unique_ptr<Options> options = GetOptions(argv);
  EXPECT_EQ(Options::Task::COMPILE, options->GetTask());
  EXPECT_EQ(Options::Language::RUST, options->TargetLanguage());
  EXPECT_EQ(false, options->FailOnParcelable());
  EXPECT_EQ(1u, options->ImportDirs().size());
  EXPECT_EQ(0u, options->PreprocessedFiles().size());
  EXPECT_EQ(string{kCompileCommandInput}, options->InputFiles().front());
  EXPECT_EQ(string{""}, options->OutputFile());
  EXPECT_EQ(string{""}, options->OutputHeaderDir());
  EXPECT_EQ(string{"src_out/"}, options->OutputDir());
  EXPECT_EQ(false, options->AutoDepFile());
  EXPECT_EQ(false, options->DependencyFileNinja());
}

TEST(OptionsTests, ParsesCompileJavaInvalid_OutRequired) {
  // -o option is required
  string expected_error = "Output directory is not set. Set with --out.";
  CaptureStderr();
  const char* arg_with_no_out_dir[] = {
      "aidl",
      "--lang=java",
      kCompileCommandIncludePath,
      "directory/input1.aidl",
      "directory/input2.aidl",
      "directory/input3.aidl",
      nullptr,
  };
  EXPECT_EQ(false, GetOptions(arg_with_no_out_dir)->Ok());
  EXPECT_THAT(GetCapturedStderr(), testing::HasSubstr(expected_error));
}

TEST(OptionsTests, ParsesCompileJavaInvalid_RejectHeaderOut) {
  string expected_error = "Header output directory is set, which does not make sense for Java.";
  CaptureStderr();
  // -h options is not for Java
  const char* arg_with_header_dir[] = {
      "aidl",          "--lang=java",           kCompileCommandIncludePath, "-o src_out",
      "-h header_out", "directory/input1.aidl", "directory/input2.aidl",    "directory/input3.aidl",
      nullptr,
  };
  EXPECT_EQ(false, GetOptions(arg_with_header_dir)->Ok());
  EXPECT_THAT(GetCapturedStderr(), testing::HasSubstr(expected_error));
}

TEST(OptionsTests, ParsesCompileCppMultiInput) {
  const char* argv[] = {
      "aidl",
      "--lang=cpp",
      kCompileCommandIncludePath,
      "-h header_out",
      "-o src_out",
      "directory/input1.aidl",
      "directory/input2.aidl",
      "directory/input3.aidl",
      nullptr,
  };
  unique_ptr<Options> options = GetOptions(argv);
  EXPECT_EQ(Options::Task::COMPILE, options->GetTask());
  EXPECT_EQ(Options::Language::CPP, options->TargetLanguage());
  EXPECT_EQ(false, options->FailOnParcelable());
  EXPECT_EQ(1u, options->ImportDirs().size());
  EXPECT_EQ(0u, options->PreprocessedFiles().size());
  const vector<string> expected_input{"directory/input1.aidl", "directory/input2.aidl",
                                      "directory/input3.aidl"};
  EXPECT_EQ(expected_input, options->InputFiles());
  EXPECT_EQ(string{""}, options->OutputFile());
  EXPECT_EQ(false, options->AutoDepFile());
  EXPECT_EQ(false, options->DependencyFileNinja());
  EXPECT_EQ(string{"header_out/"}, options->OutputHeaderDir());
  EXPECT_EQ(string{"src_out/"}, options->OutputDir());
}

TEST(OptionsTests, ParsesCompileCppInvalid_OutRequired) {
  // -o option is required
  string expected_error = "Output directory is not set. Set with --out.";
  CaptureStderr();
  const char* arg_with_no_out_dir[] = {
      "aidl",
      "--lang=cpp",
      kCompileCommandIncludePath,
      "directory/input1.aidl",
      "directory/input2.aidl",
      "directory/input3.aidl",
      nullptr,
  };
  EXPECT_EQ(false, GetOptions(arg_with_no_out_dir)->Ok());
  EXPECT_THAT(GetCapturedStderr(), testing::HasSubstr(expected_error));
}

TEST(OptionsTests, ParsesCompileCppInvalid_HeaderOutRequired) {
  // -h options is required as well
  string expected_error = "Header output directory is not set. Set with --header_out";
  CaptureStderr();
  const char* arg_with_no_header_dir[] = {
      "aidl",
      "--lang=cpp",
      kCompileCommandIncludePath,
      "-o src_out",
      "directory/input1.aidl",
      "directory/input2.aidl",
      "directory/input3.aidl",
      nullptr,
  };
  EXPECT_EQ(false, GetOptions(arg_with_no_header_dir)->Ok());
  EXPECT_THAT(GetCapturedStderr(), testing::HasSubstr(expected_error));
}

TEST(OptionsTests, ParsesCompileRustInvalid_OutRequired) {
  // -o option is required
  string expected_error = "Output directory is not set. Set with --out";
  CaptureStderr();
  const char* arg_with_no_out_dir[] = {
      "aidl",
      "--lang=rust",
      kCompileCommandIncludePath,
      "directory/input1.aidl",
      "directory/input2.aidl",
      "directory/input3.aidl",
      nullptr,
  };
  EXPECT_EQ(false, GetOptions(arg_with_no_out_dir)->Ok());
  EXPECT_THAT(GetCapturedStderr(), testing::HasSubstr(expected_error));
}

TEST(OptionsTests, ParsesCompileRustInvalid_RejectHeaderOut) {
  string expected_error = "Header output directory is set, which does not make sense for Rust.";
  CaptureStderr();
  // -h options is not for Rust
  const char* arg_with_header_dir[] = {
      "aidl",          "--lang=rust",           kCompileCommandIncludePath, "-o src_out",
      "-h header_out", "directory/input1.aidl", "directory/input2.aidl",    "directory/input3.aidl",
      nullptr,
  };
  EXPECT_EQ(false, GetOptions(arg_with_header_dir)->Ok());
  EXPECT_THAT(GetCapturedStderr(), testing::HasSubstr(expected_error));
}

TEST(OptionsTests, ParsesWarningEnableAll) {
  const char* args[] = {
      "aidl", "--lang=java", "-Weverything", "--out=out", "input.aidl", nullptr,
  };
  auto options = GetOptions(args);
  EXPECT_TRUE(options->Ok());
  auto mapping = options->GetDiagnosticMapping();
  EXPECT_EQ(DiagnosticSeverity::WARNING, mapping.Severity(DiagnosticID::interface_name));
}

TEST(OptionsTests, ParsesWarningEnableSpecificWarning) {
  const char* args[] = {
      "aidl", "--lang=java", "-Winterface-name", "--out=out", "input.aidl", nullptr,
  };
  auto options = GetOptions(args);
  EXPECT_TRUE(options->Ok());
  auto mapping = options->GetDiagnosticMapping();
  EXPECT_EQ(DiagnosticSeverity::WARNING, mapping.Severity(DiagnosticID::interface_name));
}

TEST(OptionsTests, ParsesWarningDisableSpecificWarning) {
  const char* args[] = {
      "aidl",      "--lang=java", "-Weverything", "-Wno-interface-name",
      "--out=out", "input.aidl",  nullptr,
  };
  auto options = GetOptions(args);
  EXPECT_TRUE(options->Ok());
  auto mapping = options->GetDiagnosticMapping();
  EXPECT_EQ(DiagnosticSeverity::DISABLED, mapping.Severity(DiagnosticID::interface_name));
}

TEST(OptionsTests, ParsesWarningAsErrors) {
  const char* args[] = {
      "aidl", "--lang=java", "-Werror", "-Weverything", "--out=out", "input.aidl", nullptr,
  };
  auto options = GetOptions(args);
  EXPECT_TRUE(options->Ok());
  auto mapping = options->GetDiagnosticMapping();
  EXPECT_EQ(DiagnosticSeverity::ERROR, mapping.Severity(DiagnosticID::interface_name));
}

TEST(OptionsTests, RejectsUnknownWarning) {
  const char* args[] = {
      "aidl", "--lang=java", "-Wfoobar", "--out=out", "input.aidl", nullptr,
  };
  CaptureStderr();
  auto options = GetOptions(args);
  EXPECT_FALSE(options->Ok());
  EXPECT_THAT(GetCapturedStderr(), testing::HasSubstr("unknown warning: foobar"));
}

TEST(OptionsTests, CheckApi) {
  const char* args[] = {
      "aidl", "--checkapi", "old", "new", nullptr,
  };
  CaptureStderr();
  auto options = GetOptions(args);
  EXPECT_TRUE(options->Ok());
  EXPECT_EQ("", GetCapturedStderr());
  EXPECT_EQ(Options::Task::CHECK_API, options->GetTask());
  EXPECT_EQ(Options::CheckApiLevel::COMPATIBLE, options->GetCheckApiLevel());
}

TEST(OptionsTests, CheckApiWithCompatible) {
  const char* args[] = {
      "aidl", "--checkapi=compatible", "old", "new", nullptr,
  };
  CaptureStderr();
  auto options = GetOptions(args);
  EXPECT_TRUE(options->Ok());
  EXPECT_EQ("", GetCapturedStderr());
  EXPECT_EQ(Options::Task::CHECK_API, options->GetTask());
  EXPECT_EQ(Options::CheckApiLevel::COMPATIBLE, options->GetCheckApiLevel());
}

TEST(OptionsTests, CheckApiWithEqual) {
  const char* args[] = {
      "aidl", "--checkapi=equal", "old", "new", nullptr,
  };
  CaptureStderr();
  auto options = GetOptions(args);
  EXPECT_TRUE(options->Ok());
  EXPECT_EQ("", GetCapturedStderr());
  EXPECT_EQ(Options::Task::CHECK_API, options->GetTask());
  EXPECT_EQ(Options::CheckApiLevel::EQUAL, options->GetCheckApiLevel());
}

TEST(OptionsTests, CheckApiWithUnknown) {
  const char* args[] = {
      "aidl", "--checkapi=unknown", "old", "new", nullptr,
  };
  CaptureStderr();
  auto options = GetOptions(args);
  EXPECT_FALSE(options->Ok());
  EXPECT_THAT(GetCapturedStderr(), testing::HasSubstr("Unsupported --checkapi level: 'unknown'"));
}

}  // namespace aidl
}  // namespace android
