// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <stddef.h>

#include <algorithm>

#include "testing/gtest/include/gtest/gtest.h"
#include "tools/gn/runtime_deps.h"
#include "tools/gn/scheduler.h"
#include "tools/gn/target.h"
#include "tools/gn/test_with_scope.h"

namespace {

void InitTargetWithType(TestWithScope& setup,
                        Target* target,
                        Target::OutputType type) {
  target->set_output_type(type);
  target->visibility().SetPublic();
  target->SetToolchain(setup.toolchain());
}

// Convenience function to make the correct kind of pair.
std::pair<OutputFile, const Target*> MakePair(const char* str,
                                              const Target* t) {
  return std::pair<OutputFile, const Target*>(OutputFile(str), t);
}

std::string GetVectorDescription(
    const std::vector<std::pair<OutputFile, const Target*>>& v) {
  std::string result;
  for (size_t i = 0; i < v.size(); i++) {
    if (i != 0)
      result.append(", ");
    result.append("\"" + v[i].first.value() + "\"");
  }
  return result;
}

}  // namespace

// Tests an exe depending on different types of libraries.
TEST(RuntimeDeps, Libs) {
  TestWithScope setup;
  Err err;

  // Dependency hierarchy: main(exe) -> static library
  //                                 -> shared library
  //                                 -> loadable module
  //                                 -> source set

  Target stat(setup.settings(), Label(SourceDir("//"), "stat"));
  InitTargetWithType(setup, &stat, Target::STATIC_LIBRARY);
  stat.data().push_back("//stat.dat");
  ASSERT_TRUE(stat.OnResolved(&err));

  Target shared(setup.settings(), Label(SourceDir("//"), "shared"));
  InitTargetWithType(setup, &shared, Target::SHARED_LIBRARY);
  shared.data().push_back("//shared.dat");
  ASSERT_TRUE(shared.OnResolved(&err));

  Target loadable(setup.settings(), Label(SourceDir("//"), "loadable"));
  InitTargetWithType(setup, &loadable, Target::LOADABLE_MODULE);
  loadable.data().push_back("//loadable.dat");
  ASSERT_TRUE(loadable.OnResolved(&err));

  Target set(setup.settings(), Label(SourceDir("//"), "set"));
  InitTargetWithType(setup, &set, Target::SOURCE_SET);
  set.data().push_back("//set.dat");
  ASSERT_TRUE(set.OnResolved(&err));

  Target main(setup.settings(), Label(SourceDir("//"), "main"));
  InitTargetWithType(setup, &main, Target::EXECUTABLE);
  main.private_deps().push_back(LabelTargetPair(&stat));
  main.private_deps().push_back(LabelTargetPair(&shared));
  main.private_deps().push_back(LabelTargetPair(&loadable));
  main.private_deps().push_back(LabelTargetPair(&set));
  main.data().push_back("//main.dat");
  ASSERT_TRUE(main.OnResolved(&err));

  std::vector<std::pair<OutputFile, const Target*>> result =
      ComputeRuntimeDeps(&main);

  // The result should have deps of main, all 5 dat files, libshared.so, and
  // libloadable.so.
  ASSERT_EQ(8u, result.size()) << GetVectorDescription(result);

  // The first one should always be the main exe.
  EXPECT_TRUE(MakePair("./main", &main) == result[0]);

  // The rest of the ordering is undefined. First the data files.
  EXPECT_TRUE(std::find(result.begin(), result.end(),
                        MakePair("../../stat.dat", &stat)) !=
              result.end()) << GetVectorDescription(result);
  EXPECT_TRUE(std::find(result.begin(), result.end(),
                        MakePair("../../shared.dat", &shared)) !=
              result.end()) << GetVectorDescription(result);
  EXPECT_TRUE(std::find(result.begin(), result.end(),
                        MakePair("../../loadable.dat", &loadable)) !=
              result.end()) << GetVectorDescription(result);
  EXPECT_TRUE(std::find(result.begin(), result.end(),
                        MakePair("../../set.dat", &set)) !=
              result.end()) << GetVectorDescription(result);
  EXPECT_TRUE(std::find(result.begin(), result.end(),
                        MakePair("../../main.dat", &main)) !=
              result.end()) << GetVectorDescription(result);

  // Check the static library and loadable module.
  EXPECT_TRUE(std::find(result.begin(), result.end(),
                        MakePair("./libshared.so", &shared)) !=
              result.end()) << GetVectorDescription(result);
  EXPECT_TRUE(std::find(result.begin(), result.end(),
                        MakePair("./libloadable.so", &loadable)) !=
              result.end()) << GetVectorDescription(result);
}

// Tests that executables that aren't listed as data deps aren't included in
// the output, but executables that are data deps are included.
TEST(RuntimeDeps, ExeDataDep) {
  TestWithScope setup;
  Err err;

  // Dependency hierarchy: main(exe) -> datadep(exe) -> final_in(source set)
  //                                 -> dep(exe) -> final_out(source set)
  // The final_in/out targets each have data files. final_in's should be
  // included, final_out's should not be.

  Target final_in(setup.settings(), Label(SourceDir("//"), "final_in"));
  InitTargetWithType(setup, &final_in, Target::SOURCE_SET);
  final_in.data().push_back("//final_in.dat");
  ASSERT_TRUE(final_in.OnResolved(&err));

  Target datadep(setup.settings(), Label(SourceDir("//"), "datadep"));
  InitTargetWithType(setup, &datadep, Target::EXECUTABLE);
  datadep.private_deps().push_back(LabelTargetPair(&final_in));
  ASSERT_TRUE(datadep.OnResolved(&err));

  Target final_out(setup.settings(), Label(SourceDir("//"), "final_out"));
  InitTargetWithType(setup, &final_out, Target::SOURCE_SET);
  final_out.data().push_back("//final_out.dat");
  ASSERT_TRUE(final_out.OnResolved(&err));

  Target dep(setup.settings(), Label(SourceDir("//"), "dep"));
  InitTargetWithType(setup, &dep, Target::EXECUTABLE);
  dep.private_deps().push_back(LabelTargetPair(&final_out));
  ASSERT_TRUE(dep.OnResolved(&err));

  Target main(setup.settings(), Label(SourceDir("//"), "main"));
  InitTargetWithType(setup, &main, Target::EXECUTABLE);
  main.private_deps().push_back(LabelTargetPair(&dep));
  main.data_deps().push_back(LabelTargetPair(&datadep));
  ASSERT_TRUE(main.OnResolved(&err));

  std::vector<std::pair<OutputFile, const Target*>> result =
      ComputeRuntimeDeps(&main);

  // The result should have deps of main, datadep, final_in.dat
  ASSERT_EQ(3u, result.size()) << GetVectorDescription(result);

  // The first one should always be the main exe.
  EXPECT_TRUE(MakePair("./main", &main) == result[0]);

  // The rest of the ordering is undefined.
  EXPECT_TRUE(std::find(result.begin(), result.end(),
                        MakePair("./datadep", &datadep)) !=
              result.end()) << GetVectorDescription(result);
  EXPECT_TRUE(std::find(result.begin(), result.end(),
                        MakePair("../../final_in.dat", &final_in)) !=
              result.end()) << GetVectorDescription(result);
}

// Tests that action and copy outputs are considered if they're data deps, but
// not if they're regular deps. Action and copy "data" files are always
// included.
TEST(RuntimeDeps, ActionOutputs) {
  TestWithScope setup;
  Err err;

  // Dependency hierarchy: main(exe) -> datadep (action)
  //                                 -> datadep_copy (copy)
  //                                 -> dep (action)
  //                                 -> dep_copy (copy)

  Target datadep(setup.settings(), Label(SourceDir("//"), "datadep"));
  InitTargetWithType(setup, &datadep, Target::ACTION);
  datadep.data().push_back("//datadep.data");
  datadep.action_values().outputs() =
      SubstitutionList::MakeForTest("//datadep.output");
  ASSERT_TRUE(datadep.OnResolved(&err));

  Target datadep_copy(setup.settings(), Label(SourceDir("//"), "datadep_copy"));
  InitTargetWithType(setup, &datadep_copy, Target::COPY_FILES);
  datadep_copy.sources().push_back(SourceFile("//input"));
  datadep_copy.data().push_back("//datadep_copy.data");
  datadep_copy.action_values().outputs() =
      SubstitutionList::MakeForTest("//datadep_copy.output");
  ASSERT_TRUE(datadep_copy.OnResolved(&err));

  Target dep(setup.settings(), Label(SourceDir("//"), "dep"));
  InitTargetWithType(setup, &dep, Target::ACTION);
  dep.data().push_back("//dep.data");
  dep.action_values().outputs() =
      SubstitutionList::MakeForTest("//dep.output");
  ASSERT_TRUE(dep.OnResolved(&err));

  Target dep_copy(setup.settings(), Label(SourceDir("//"), "dep_copy"));
  InitTargetWithType(setup, &dep_copy, Target::COPY_FILES);
  dep_copy.sources().push_back(SourceFile("//input"));
  dep_copy.data().push_back("//dep_copy/data/");  // Tests a directory.
  dep_copy.action_values().outputs() =
      SubstitutionList::MakeForTest("//dep_copy.output");
  ASSERT_TRUE(dep_copy.OnResolved(&err));

  Target main(setup.settings(), Label(SourceDir("//"), "main"));
  InitTargetWithType(setup, &main, Target::EXECUTABLE);
  main.private_deps().push_back(LabelTargetPair(&dep));
  main.private_deps().push_back(LabelTargetPair(&dep_copy));
  main.data_deps().push_back(LabelTargetPair(&datadep));
  main.data_deps().push_back(LabelTargetPair(&datadep_copy));
  ASSERT_TRUE(main.OnResolved(&err));

  std::vector<std::pair<OutputFile, const Target*>> result =
      ComputeRuntimeDeps(&main);

  // The result should have deps of main, both datadeps files, but only
  // the data file from dep.
  ASSERT_EQ(7u, result.size()) << GetVectorDescription(result);

  // The first one should always be the main exe.
  EXPECT_TRUE(MakePair("./main", &main) == result[0]);

  // The rest of the ordering is undefined.
  EXPECT_TRUE(std::find(result.begin(), result.end(),
                        MakePair("../../datadep.data", &datadep)) !=
              result.end()) << GetVectorDescription(result);
  EXPECT_TRUE(std::find(result.begin(), result.end(),
                        MakePair("../../datadep_copy.data", &datadep_copy)) !=
              result.end()) << GetVectorDescription(result);
  EXPECT_TRUE(std::find(result.begin(), result.end(),
                        MakePair("../../datadep.output", &datadep)) !=
              result.end()) << GetVectorDescription(result);
  EXPECT_TRUE(std::find(result.begin(), result.end(),
                        MakePair("../../datadep_copy.output", &datadep_copy)) !=
              result.end()) << GetVectorDescription(result);
  EXPECT_TRUE(std::find(result.begin(), result.end(),
                        MakePair("../../dep.data", &dep)) !=
              result.end()) << GetVectorDescription(result);
  EXPECT_TRUE(std::find(result.begin(), result.end(),
                        MakePair("../../dep_copy/data/", &dep_copy)) !=
              result.end()) << GetVectorDescription(result);

  // Explicitly asking for the runtime deps of an action target only includes
  // the data and not all outputs.
  result = ComputeRuntimeDeps(&dep);
  ASSERT_EQ(1u, result.size());
  EXPECT_TRUE(MakePair("../../dep.data", &dep) == result[0]);
}

// Tests that the search for dependencies terminates at a bundle target,
// ignoring any shared libraries or loadable modules that get copied into the
// bundle.
TEST(RuntimeDeps, CreateBundle) {
  TestWithScope setup;
  Err err;

  // Dependency hierarchy:
  // main(exe) -> dep(bundle) -> dep(shared_library) -> dep(source set)
  //                          -> dep(bundle_data) -> dep(loadable_module)
  //                                                      -> data(lm.data)
  //                          -> datadep(datadep) -> data(dd.data)

  const SourceDir source_dir("//");
  const std::string& build_dir = setup.build_settings()->build_dir().value();

  Target loadable_module(setup.settings(),
                         Label(source_dir, "loadable_module"));
  InitTargetWithType(setup, &loadable_module, Target::LOADABLE_MODULE);
  loadable_module.data().push_back("//lm.data");
  ASSERT_TRUE(loadable_module.OnResolved(&err));

  Target module_data(setup.settings(), Label(source_dir, "module_data"));
  InitTargetWithType(setup, &module_data, Target::BUNDLE_DATA);
  module_data.private_deps().push_back(LabelTargetPair(&loadable_module));
  module_data.bundle_data().file_rules().push_back(BundleFileRule(
      nullptr,
      std::vector<SourceFile>{SourceFile(build_dir + "loadable_module.so")},
      SubstitutionPattern::MakeForTest("{{bundle_resources_dir}}")));
  ASSERT_TRUE(module_data.OnResolved(&err));

  Target source_set(setup.settings(), Label(source_dir, "sources"));
  InitTargetWithType(setup, &source_set, Target::SOURCE_SET);
  source_set.sources().push_back(SourceFile(source_dir.value() + "foo.cc"));
  ASSERT_TRUE(source_set.OnResolved(&err));

  Target dylib(setup.settings(), Label(source_dir, "dylib"));
  dylib.set_output_prefix_override(true);
  dylib.set_output_extension("");
  dylib.set_output_name("Bundle");
  InitTargetWithType(setup, &dylib, Target::SHARED_LIBRARY);
  dylib.private_deps().push_back(LabelTargetPair(&source_set));
  ASSERT_TRUE(dylib.OnResolved(&err));

  Target dylib_data(setup.settings(), Label(source_dir, "dylib_data"));
  InitTargetWithType(setup, &dylib_data, Target::BUNDLE_DATA);
  dylib_data.private_deps().push_back(LabelTargetPair(&dylib));
  dylib_data.bundle_data().file_rules().push_back(BundleFileRule(
      nullptr, std::vector<SourceFile>{SourceFile(build_dir + "dylib")},
      SubstitutionPattern::MakeForTest("{{bundle_executable_dir}}")));
  ASSERT_TRUE(dylib_data.OnResolved(&err));

  Target data_dep(setup.settings(), Label(source_dir, "datadep"));
  InitTargetWithType(setup, &data_dep, Target::EXECUTABLE);
  data_dep.data().push_back("//dd.data");
  ASSERT_TRUE(data_dep.OnResolved(&err));

  Target bundle(setup.settings(), Label(source_dir, "bundle"));
  InitTargetWithType(setup, &bundle, Target::CREATE_BUNDLE);
  const std::string root_dir(build_dir + "Bundle.framework/Versions/A/");
  bundle.bundle_data().root_dir() = SourceDir(root_dir);
  bundle.bundle_data().resources_dir() = SourceDir(root_dir + "Resources");
  bundle.bundle_data().executable_dir() = SourceDir(root_dir + "MacOS");
  bundle.private_deps().push_back(LabelTargetPair(&dylib_data));
  bundle.private_deps().push_back(LabelTargetPair(&module_data));
  bundle.data_deps().push_back(LabelTargetPair(&data_dep));
  bundle.data().push_back("//b.data");
  ASSERT_TRUE(bundle.OnResolved(&err));

  Target main(setup.settings(), Label(source_dir, "main"));
  InitTargetWithType(setup, &main, Target::EXECUTABLE);
  main.data_deps().push_back(LabelTargetPair(&bundle));
  ASSERT_TRUE(main.OnResolved(&err));

  std::vector<std::pair<OutputFile, const Target*>> result =
      ComputeRuntimeDeps(&main);

  // The result should have deps of main, datadep, final_in.dat
  ASSERT_EQ(5u, result.size()) << GetVectorDescription(result);

  // The first one should always be the main exe.
  EXPECT_EQ(MakePair("./main", &main), result[0]);

  // The rest of the ordering is undefined.

  // The framework bundle's internal dependencies should not be incldued.
  EXPECT_TRUE(std::find(result.begin(), result.end(),
                        MakePair("Bundle.framework/", &bundle)) !=
              result.end()) << GetVectorDescription(result);
  // But direct data and data dependencies should be.
  EXPECT_TRUE(std::find(result.begin(), result.end(),
                        MakePair("./datadep", &data_dep)) !=
              result.end()) << GetVectorDescription(result);
  EXPECT_TRUE(std::find(result.begin(), result.end(),
                        MakePair("../../dd.data", &data_dep)) !=
              result.end()) << GetVectorDescription(result);
  EXPECT_TRUE(std::find(result.begin(), result.end(),
                        MakePair("../../b.data", &bundle)) !=
              result.end()) << GetVectorDescription(result);
}

// Tests that a dependency duplicated in regular and data deps is processed
// as a data dep.
TEST(RuntimeDeps, Dupe) {
  TestWithScope setup;
  Err err;

  Target action(setup.settings(), Label(SourceDir("//"), "action"));
  InitTargetWithType(setup, &action, Target::ACTION);
  action.action_values().outputs() =
      SubstitutionList::MakeForTest("//action.output");
  ASSERT_TRUE(action.OnResolved(&err));

  Target target(setup.settings(), Label(SourceDir("//"), "foo"));
  InitTargetWithType(setup, &target, Target::EXECUTABLE);
  target.private_deps().push_back(LabelTargetPair(&action));
  target.data_deps().push_back(LabelTargetPair(&action));
  ASSERT_TRUE(target.OnResolved(&err));

  // The results should be the executable and the copy output.
  std::vector<std::pair<OutputFile, const Target*>> result =
      ComputeRuntimeDeps(&target);
  EXPECT_TRUE(std::find(result.begin(), result.end(),
                        MakePair("../../action.output", &action)) !=
              result.end()) << GetVectorDescription(result);
}

// Tests that actions can't have output substitutions.
TEST(RuntimeDeps, WriteRuntimeDepsVariable) {
  Scheduler scheduler;
  TestWithScope setup;
  Err err;

  // Should refuse to write files outside of the output dir.
  EXPECT_FALSE(setup.ExecuteSnippet(
      "group(\"foo\") { write_runtime_deps = \"//foo.txt\" }", &err));

  // Should fail for garbage inputs.
  err = Err();
  EXPECT_FALSE(setup.ExecuteSnippet(
      "group(\"foo\") { write_runtime_deps = 0 }", &err));

  // Should be able to write inside the out dir, and shouldn't write the one
  // in the else clause.
  err = Err();
  EXPECT_TRUE(setup.ExecuteSnippet(
      "if (true) {\n"
      "  group(\"foo\") { write_runtime_deps = \"//out/Debug/foo.txt\" }\n"
      "} else {\n"
      "  group(\"bar\") { write_runtime_deps = \"//out/Debug/bar.txt\" }\n"
      "}", &err));
  EXPECT_EQ(1U, setup.items().size());
  EXPECT_EQ(1U, scheduler.GetWriteRuntimeDepsTargets().size());
}
