/*
 * 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 <gtest/gtest.h>

using std::cerr;
using std::endl;
using std::string;
using std::unique_ptr;
using std::vector;

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());
  EXPECT_EQ(false, options->GenParcelableToString());

  const char* argv[] = {
      "aidl",  "-b", kCompileCommandIncludePath, kCompileCommandInput, "--parcelable-to-string",
      nullptr,
  };
  options = GetOptions(argv);
  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());
  EXPECT_EQ(true, options->GenParcelableToString());
}

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());
  EXPECT_EQ(false, options->GenParcelableToString());

  const char* argv[] = {
      "aidl-cpp",
      kCompileCommandIncludePath,
      kCompileDepFile,
      kCompileCommandInput,
      kCompileCommandHeaderDir,
      kCompileCommandCppOutput,
      "--parcelable-to-string",
      nullptr,
  };
  options = GetOptions(argv, 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());
  EXPECT_EQ(true, options->GenParcelableToString());
}

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());
  EXPECT_EQ(false, options->GenParcelableToString());
}

TEST(OptionsTests, ParsesCompileJavaInvalid) {
  // -o option is required
  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());

  // -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());
}

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) {
  // -o option is required
  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());

  // -h options is required as well
  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());
}

TEST(OptionsTests, ParsesCompileRustInvalid) {
  // -o option is required
  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());

  // -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());
}

}  // namespace aidl
}  // namespace android
