/*
 * 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 <memory>
#include <string>
#include <vector>

#include <android-base/logging.h>
#include <gtest/gtest.h>

#include "aidl.h"
#include "options.h"
#include "tests/fake_io_delegate.h"
#include "tests/test_data.h"
#include "tests/test_util.h"

using android::aidl::test::CanonicalNameToPath;
using android::aidl::test::FakeIoDelegate;
using std::string;
using std::unique_ptr;
using std::vector;

namespace android {
namespace aidl {

class EndToEndTest : public ::testing::Test {
 protected:
  virtual void SetUp() {
  }

  void AddStubAidls(const char** parcelables, const char** interfaces,
                    const char* cpp_header=nullptr) {
    for ( ; *parcelables; ++parcelables) {
      io_delegate_.AddStubParcelable(
          *parcelables, (cpp_header) ? cpp_header : "");
    }
    for ( ; *interfaces; ++interfaces) {
      io_delegate_.AddStubInterface(*interfaces);
    }
  }

  void CheckFileContents(const string& rel_path,
                         const string& expected_content) {
    string actual_content;
    ASSERT_TRUE(io_delegate_.GetWrittenContents(rel_path, &actual_content))
        << "Expected aidl to write to " << rel_path << " but it did not.";

    if (actual_content == expected_content) {
      return;  // success!
    }

    test::PrintDiff(expected_content, actual_content);
    FAIL() << "Actual contents of " << rel_path
           << " did not match expected content";
  }

  FakeIoDelegate io_delegate_;
};

TEST_F(EndToEndTest, IExampleInterface) {
  using namespace ::android::aidl::test_data::example_interface;

  vector<string> args = {
    "aidl",
    "-b",
    "-I .",
    "-d an/arbitrary/path/to/dep.P",
    CanonicalNameToPath(kCanonicalName, ".aidl"),
    kJavaOutputPath};
  Options options = Options::From(args);

  // Load up our fake file system with data.
  io_delegate_.SetFileContents(options.InputFiles().front(), kInterfaceDefinition);
  io_delegate_.AddCompoundParcelable("android.test.CompoundParcelable",
                                     {"Subclass1", "Subclass2"});
  AddStubAidls(kImportedParcelables, kImportedInterfaces);

  // Check that we parse correctly.
  EXPECT_EQ(android::aidl::compile_aidl(options, io_delegate_), 0);
  CheckFileContents(kJavaOutputPath, kExpectedJavaOutput);
  CheckFileContents(options.DependencyFile(), kExpectedJavaDepsOutput);
}

TEST_F(EndToEndTest, IExampleInterface_WithTrace) {
  using namespace ::android::aidl::test_data::example_interface;

  vector<string> args = {
    "aidl",
    "-b",
    "-I .",
    "-t", //trace
    "-d an/arbitrary/path/to/dep.P",
    CanonicalNameToPath(kCanonicalName, ".aidl"),
    kJavaOutputPath};
  Options options = Options::From(args);

  // Load up our fake file system with data.
  io_delegate_.SetFileContents(options.InputFiles().front(), kInterfaceDefinition);
  io_delegate_.AddCompoundParcelable("android.test.CompoundParcelable",
                                     {"Subclass1", "Subclass2"});
  AddStubAidls(kImportedParcelables, kImportedInterfaces);

  // Check that we parse correctly.
  EXPECT_EQ(android::aidl::compile_aidl(options, io_delegate_), 0);
  CheckFileContents(kJavaOutputPath, kExpectedJavaOutputWithTrace);
  CheckFileContents(options.DependencyFile(), kExpectedJavaDepsOutput);
}

TEST_F(EndToEndTest, IExampleInterface_WithTransactionNames) {
  using namespace ::android::aidl::test_data::example_interface;

  vector<string> args = {
    "aidl",
    "-b",
    "-I .",
    "--transaction_name", //trace
    "-d an/arbitrary/path/to/dep.P",
    CanonicalNameToPath(kCanonicalName, ".aidl"),
    kJavaOutputPath};
  Options options = Options::From(args);

  // Load up our fake file system with data.
  io_delegate_.SetFileContents(options.InputFiles().front(), kInterfaceDefinition);
  io_delegate_.AddCompoundParcelable("android.test.CompoundParcelable",
                                     {"Subclass1", "Subclass2"});
  AddStubAidls(kImportedParcelables, kImportedInterfaces);

  // Check that we parse correctly.
  EXPECT_EQ(android::aidl::compile_aidl(options, io_delegate_), 0);
  CheckFileContents(kJavaOutputPath, kExpectedJavaOutputWithTransactionNames);
  CheckFileContents(options.DependencyFile(), kExpectedJavaDepsOutput);
}

TEST_F(EndToEndTest, IExampleInterface_Outlining) {
  using namespace ::android::aidl::test_data::example_interface;

  vector<string> args = {
    "aidl",
    "-b",
    "-I .",
    "-d an/arbitrary/path/to/dep.P",
    CanonicalNameToPath(kCanonicalName, ".aidl"),
    kJavaOutputPath};
  Options options = Options::From(args);
  options.onTransact_outline_threshold_ = 4;
  options.onTransact_non_outline_count_ = 3;

  // Load up our fake file system with data.
  io_delegate_.SetFileContents(options.InputFiles().front(), kInterfaceDefinitionOutlining);
  io_delegate_.AddCompoundParcelable("android.test.CompoundParcelable",
                                     {"Subclass1", "Subclass2"});
  AddStubAidls(kImportedParcelables, kImportedInterfaces);

  // Check that we parse correctly.
  EXPECT_EQ(android::aidl::compile_aidl(options, io_delegate_), 0);
  CheckFileContents(kJavaOutputPath, kExpectedJavaOutputOutlining);
  CheckFileContents(options.DependencyFile(), kExpectedJavaDepsOutput);
}

TEST_F(EndToEndTest, IExampleInterface_WithVersion) {
  using namespace ::android::aidl::test_data::example_interface;

  vector<string> args = {
    "aidl",
    "-b",
    "-I .",
    "-d an/arbitrary/path/to/dep.P",
    "--version=10",
    CanonicalNameToPath(kCanonicalName, ".aidl"),
    kJavaOutputPath};
  Options options = Options::From(args);
  options.onTransact_outline_threshold_ = 4;
  options.onTransact_non_outline_count_ = 3;

  // Load up our fake file system with data.
  io_delegate_.SetFileContents(options.InputFiles().front(), kInterfaceDefinitionOutlining);
  io_delegate_.AddCompoundParcelable("android.test.CompoundParcelable",
                                     {"Subclass1", "Subclass2"});
  AddStubAidls(kImportedParcelables, kImportedInterfaces);

  // Check that we parse correctly.
  EXPECT_EQ(android::aidl::compile_aidl(options, io_delegate_), 0);
  CheckFileContents(kJavaOutputPath, kExpectedJavaOutputWithVersion);
  CheckFileContents(options.DependencyFile(), kExpectedJavaDepsOutput);
}


TEST_F(EndToEndTest, IPingResponderCpp) {
  using namespace ::android::aidl::test_data::ping_responder;

  vector<string> args = {
    "aidl-cpp",
    "-d deps.P",
    "-I .",
    CanonicalNameToPath(kCanonicalName, ".aidl"),
    kGenHeaderDir,
    kCppOutputPath};
  Options options = Options::From(args);

  // Set up input paths.
  io_delegate_.SetFileContents(CanonicalNameToPath(kCanonicalName, ".aidl"), kInterfaceDefinition);
  AddStubAidls(kImportedParcelables, kImportedInterfaces, kCppParcelableHeader);

  // Check that we parse and generate code correctly.
  EXPECT_EQ(android::aidl::compile_aidl(options, io_delegate_), 0);
  CheckFileContents(kCppOutputPath, kExpectedCppOutput);
  CheckFileContents(kGenInterfaceHeaderPath, kExpectedIHeaderOutput);
  CheckFileContents(kGenClientHeaderPath, kExpectedBpHeaderOutput);
  CheckFileContents(kGenServerHeaderPath, kExpectedBnHeaderOutput);
  CheckFileContents(options.DependencyFile(), kExpectedCppDepsOutput);
}

TEST_F(EndToEndTest, IPingResponderCpp_WithVersion) {
  using namespace ::android::aidl::test_data::ping_responder;

  vector<string> args = {
    "aidl-cpp",
    "-d deps.P",
    "-I .",
    "--version=10",
    CanonicalNameToPath(kCanonicalName, ".aidl"),
    kGenHeaderDir,
    kCppOutputPath};
  Options options = Options::From(args);

  // Set up input paths.
  io_delegate_.SetFileContents(CanonicalNameToPath(kCanonicalName, ".aidl"), kInterfaceDefinition);
  AddStubAidls(kImportedParcelables, kImportedInterfaces, kCppParcelableHeader);

  // Check that we parse and generate code correctly.
  EXPECT_EQ(android::aidl::compile_aidl(options, io_delegate_), 0);
  CheckFileContents(kCppOutputPath, kExpectedCppOutputWithVersion);
  CheckFileContents(kGenInterfaceHeaderPath, kExpectedIHeaderOutputWithVersion);
  CheckFileContents(kGenClientHeaderPath, kExpectedBpHeaderOutputWithVersion);
  CheckFileContents(kGenServerHeaderPath, kExpectedBnHeaderOutputWithVersion);
  CheckFileContents(options.DependencyFile(), kExpectedCppDepsOutput);
}

TEST_F(EndToEndTest, StringConstantsInCpp) {
  using namespace ::android::aidl::test_data::string_constants;

  vector<string> args = {
    "aidl-cpp",
    CanonicalNameToPath(kCanonicalName, ".aidl"),
    kGenHeaderDir,
    kCppOutputPath};
  Options options = Options::From(args);

  // Set up input paths.
  io_delegate_.SetFileContents(CanonicalNameToPath(kCanonicalName, ".aidl"), kInterfaceDefinition);

  // Check that we parse and generate code correctly.
  EXPECT_EQ(android::aidl::compile_aidl(options, io_delegate_), 0);
  CheckFileContents(kCppOutputPath, kExpectedCppOutput);
  CheckFileContents(kGenInterfaceHeaderPath, kExpectedIHeaderOutput);
}

TEST_F(EndToEndTest, StringConstantsInJava) {
  using namespace ::android::aidl::test_data::string_constants;

  vector<string> args = {
    "aidl",
    "-b",
    CanonicalNameToPath(kCanonicalName, ".aidl"),
    kJavaOutputPath};
  Options options = Options::From(args);

  // Load up our fake file system with data.
  io_delegate_.SetFileContents(CanonicalNameToPath(kCanonicalName, ".aidl"), kInterfaceDefinition);

  // Check that we parse correctly.
  EXPECT_EQ(android::aidl::compile_aidl(options, io_delegate_), 0);
  CheckFileContents(kJavaOutputPath, kExpectedJavaOutput);
}

TEST_F(EndToEndTest, StringConstantsInCpp_WithVersion) {
  using namespace ::android::aidl::test_data::string_constants;

  vector<string> args = {
    "aidl-cpp",
    "--version=10",
    CanonicalNameToPath(kCanonicalName, ".aidl"),
    kGenHeaderDir,
    kCppOutputPath};
  Options options = Options::From(args);

  // Set up input paths.
  io_delegate_.SetFileContents(CanonicalNameToPath(kCanonicalName, ".aidl"), kInterfaceDefinition);

  // Check that we parse and generate code correctly.
  EXPECT_EQ(android::aidl::compile_aidl(options, io_delegate_), 0);
  CheckFileContents(kCppOutputPath, kExpectedCppOutputWithVersion);
  CheckFileContents(kGenInterfaceHeaderPath, kExpectedIHeaderOutputWithVersion);
}

TEST_F(EndToEndTest, StringConstantsInJava_WithVersion) {
  using namespace ::android::aidl::test_data::string_constants;

  vector<string> args = {
    "aidl",
    "-b",
    "--version=10",
    CanonicalNameToPath(kCanonicalName, ".aidl"),
    kJavaOutputPath};
  Options options = Options::From(args);

  // Load up our fake file system with data.
  io_delegate_.SetFileContents(CanonicalNameToPath(kCanonicalName, ".aidl"), kInterfaceDefinition);

  // Check that we parse correctly.
  EXPECT_EQ(android::aidl::compile_aidl(options, io_delegate_), 0);
  CheckFileContents(kJavaOutputPath, kExpectedJavaOutputWithVersion);
}

}  // namespace android
}  // namespace aidl
