// Copyright (c) 2013 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 <map>
#include <set>

#include "base/command_line.h"
#include "base/files/file_util.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "gn/commands.h"
#include "gn/config_values_extractors.h"
#include "gn/deps_iterator.h"
#include "gn/filesystem_utils.h"
#include "gn/input_file.h"
#include "gn/item.h"
#include "gn/setup.h"
#include "gn/standard_out.h"
#include "gn/switches.h"
#include "gn/target.h"
#include "gn/unique_vector.h"

namespace commands {

namespace {

using TargetSet = TargetSet;
using TargetVector = std::vector<const Target*>;

// Maps targets to the list of targets that depend on them.
using DepMap = std::multimap<const Target*, const Target*>;

// Populates the reverse dependency map for the targets in the Setup.
void FillDepMap(Setup* setup, DepMap* dep_map) {
  for (auto* target : setup->builder().GetAllResolvedTargets()) {
    for (const auto& dep_pair : target->GetDeps(Target::DEPS_ALL))
      dep_map->insert(std::make_pair(dep_pair.ptr, target));
    for (const auto& validation_pair : target->validations())
      dep_map->insert(std::make_pair(validation_pair.ptr, target));
  }
}

// Forward declaration for function below.
size_t RecursivePrintTargetDeps(const DepMap& dep_map,
                                const Target* target,
                                TargetSet* seen_targets,
                                int indent_level);

// Prints the target and its dependencies in tree form. If the set is non-null,
// new targets encountered will be added to the set, and if a ref is in the set
// already, it will not be recused into. When the set is null, all refs will be
// printed.
//
// Returns the number of items printed.
size_t RecursivePrintTarget(const DepMap& dep_map,
                            const Target* target,
                            TargetSet* seen_targets,
                            int indent_level) {
  std::string indent(indent_level * 2, ' ');
  size_t count = 1;

  // Only print the toolchain for non-default-toolchain targets.
  OutputString(indent + target->label().GetUserVisibleName(
                            !target->settings()->is_default()));

  bool print_children = true;
  if (seen_targets) {
    if (!seen_targets->add(target)) {
      // Already seen.
      print_children = false;
      // Only print "..." if something is actually elided, which means that
      // the current target has children.
      if (dep_map.lower_bound(target) != dep_map.upper_bound(target))
        OutputString("...");
    }
  }

  OutputString("\n");
  if (print_children) {
    count += RecursivePrintTargetDeps(dep_map, target, seen_targets,
                                      indent_level + 1);
  }
  return count;
}

// Prints refs of the given target (not the target itself). See
// RecursivePrintTarget.
size_t RecursivePrintTargetDeps(const DepMap& dep_map,
                                const Target* target,
                                TargetSet* seen_targets,
                                int indent_level) {
  DepMap::const_iterator dep_begin = dep_map.lower_bound(target);
  DepMap::const_iterator dep_end = dep_map.upper_bound(target);
  size_t count = 0;
  for (DepMap::const_iterator cur_dep = dep_begin; cur_dep != dep_end;
       cur_dep++) {
    count += RecursivePrintTarget(dep_map, cur_dep->second, seen_targets,
                                  indent_level);
  }
  return count;
}

void RecursiveCollectChildRefs(const DepMap& dep_map,
                               const Target* target,
                               TargetSet* results);

// Recursively finds all targets that reference the given one, and additionally
// adds the current one to the list.
void RecursiveCollectRefs(const DepMap& dep_map,
                          const Target* target,
                          TargetSet* results) {
  if (!results->add(target))
    return;  // Already found this target.
  RecursiveCollectChildRefs(dep_map, target, results);
}

// Recursively finds all targets that reference the given one.
void RecursiveCollectChildRefs(const DepMap& dep_map,
                               const Target* target,
                               TargetSet* results) {
  DepMap::const_iterator dep_begin = dep_map.lower_bound(target);
  DepMap::const_iterator dep_end = dep_map.upper_bound(target);
  for (DepMap::const_iterator cur_dep = dep_begin; cur_dep != dep_end;
       cur_dep++)
    RecursiveCollectRefs(dep_map, cur_dep->second, results);
}

bool TargetReferencesConfig(const Target* target, const Config* config) {
  for (const LabelConfigPair& cur : target->configs()) {
    if (cur.ptr == config)
      return true;
  }
  for (const LabelConfigPair& cur : target->public_configs()) {
    if (cur.ptr == config)
      return true;
  }
  return false;
}

void GetTargetsReferencingConfig(Setup* setup,
                                 const std::vector<const Target*>& all_targets,
                                 const Config* config,
                                 bool default_toolchain_only,
                                 UniqueVector<const Target*>* matches) {
  Label default_toolchain = setup->loader()->default_toolchain_label();
  for (auto* target : all_targets) {
    if (default_toolchain_only) {
      // Only check targets in the default toolchain.
      if (target->label().GetToolchainLabel() != default_toolchain)
        continue;
    }
    if (TargetReferencesConfig(target, config))
      matches->push_back(target);
  }
}

// Returns the number of matches printed.
size_t DoTreeOutput(const DepMap& dep_map,
                    const UniqueVector<const Target*>& implicit_target_matches,
                    const UniqueVector<const Target*>& explicit_target_matches,
                    bool all) {
  TargetSet seen_targets;
  size_t count = 0;

  // Implicit targets don't get printed themselves.
  for (const Target* target : implicit_target_matches) {
    if (all)
      count += RecursivePrintTargetDeps(dep_map, target, nullptr, 0);
    else
      count += RecursivePrintTargetDeps(dep_map, target, &seen_targets, 0);
  }

  // Explicit targets appear in the output.
  for (const Target* target : implicit_target_matches) {
    if (all)
      count += RecursivePrintTarget(dep_map, target, nullptr, 0);
    else
      count += RecursivePrintTarget(dep_map, target, &seen_targets, 0);
  }

  return count;
}

// Returns the number of matches printed.
size_t DoAllListOutput(
    const DepMap& dep_map,
    const UniqueVector<const Target*>& implicit_target_matches,
    const UniqueVector<const Target*>& explicit_target_matches) {
  // Output recursive dependencies, uniquified and flattened.
  TargetSet results;

  for (const Target* target : implicit_target_matches)
    RecursiveCollectChildRefs(dep_map, target, &results);
  for (const Target* target : explicit_target_matches) {
    // Explicit targets also get added to the output themselves.
    results.insert(target);
    RecursiveCollectChildRefs(dep_map, target, &results);
  }

  FilterAndPrintTargetSet(false, results);
  return results.size();
}

// Returns the number of matches printed.
size_t DoDirectListOutput(
    const DepMap& dep_map,
    const UniqueVector<const Target*>& implicit_target_matches,
    const UniqueVector<const Target*>& explicit_target_matches) {
  TargetSet results;

  // Output everything that refers to the implicit ones.
  for (const Target* target : implicit_target_matches) {
    DepMap::const_iterator dep_begin = dep_map.lower_bound(target);
    DepMap::const_iterator dep_end = dep_map.upper_bound(target);
    for (DepMap::const_iterator cur_dep = dep_begin; cur_dep != dep_end;
         cur_dep++)
      results.insert(cur_dep->second);
  }

  // And just output the explicit ones directly (these are the target matches
  // when referring to what references a file or config).
  for (const Target* target : explicit_target_matches)
    results.insert(target);

  FilterAndPrintTargetSet(false, results);
  return results.size();
}

}  // namespace

const char kRefs[] = "refs";
const char kRefs_HelpShort[] = "refs: Find stuff referencing a target or file.";
const char kRefs_Help[] =
    R"(gn refs

  gn refs <out_dir> (<label_pattern>|<label>|<file>|@<response_file>)* [--all]
          [--default-toolchain] [--as=...] [--testonly=...] [--type=...]

  Finds reverse dependencies (which targets reference something). The input is
  a list containing:

   - Target label: The result will be which targets depend on it.

   - Config label: The result will be which targets list the given config in
     its "configs" or "public_configs" list.

   - Label pattern: The result will be which targets depend on any target
     matching the given pattern. Patterns will not match configs. These are not
     general regular expressions, see "gn help label_pattern" for details.

   - File name: The result will be which targets list the given file in its
     "inputs", "sources", "public", "data", or "outputs". Any input that does
     not contain wildcards and does not match a target or a config will be
     treated as a file.

   - Response file: If the input starts with an "@", it will be interpreted as
     a path to a file containing a list of labels or file names, one per line.
     This allows us to handle long lists of inputs without worrying about
     command line limits.

Options

  --all
      When used without --tree, will recurse and display all unique
      dependencies of the given targets. For example, if the input is a target,
      this will output all targets that depend directly or indirectly on the
      input. If the input is a file, this will output all targets that depend
      directly or indirectly on that file.

      When used with --tree, turns off eliding to show a complete tree.

)"

    TARGET_PRINTING_MODE_COMMAND_LINE_HELP "\n" DEFAULT_TOOLCHAIN_SWITCH_HELP

    R"(
  -q
     Quiet. If nothing matches, don't print any output. Without this option, if
     there are no matches there will be an informational message printed which
     might interfere with scripts processing the output.

)"

    TARGET_TESTONLY_FILTER_COMMAND_LINE_HELP

    R"(
  --tree
      Outputs a reverse dependency tree from the given target. Duplicates will
      be elided. Combine with --all to see a full dependency tree.

      Tree output can not be used with the filtering or output flags: --as,
      --type, --testonly.

)"

    TARGET_TYPE_FILTER_COMMAND_LINE_HELP

    R"(
  --relation=(source|public|input|data|script|output)
      Restricts output to targets which refer to input files by a specific
      relation. Defaults to any relation. Can be provided multiple times to
      include multiple relations.
    )"

    R"(

Examples (target input)

  gn refs out/Debug //gn:gn
      Find all targets depending on the given exact target name.

  gn refs out/Debug //base:i18n --as=buildfile | xargs gvim
      Edit all .gn files containing references to //base:i18n

  gn refs out/Debug //base --all
      List all targets depending directly or indirectly on //base:base.

  gn refs out/Debug "//base/*"
      List all targets depending directly on any target in //base or
      its subdirectories.

  gn refs out/Debug "//base:*"
      List all targets depending directly on any target in
      //base/BUILD.gn.

  gn refs out/Debug //base --tree
      Print a reverse dependency tree of //base:base

Examples (file input)

  gn refs out/Debug //base/macros.h
      Print target(s) listing //base/macros.h as a source.

  gn refs out/Debug //base/macros.h --tree
      Display a reverse dependency tree to get to the given file. This
      will show how dependencies will reference that file.

  gn refs out/Debug //base/macros.h //base/at_exit.h --all
      Display all unique targets with some dependency path to a target
      containing either of the given files as a source.

  gn refs out/Debug //base/macros.h --testonly=true --type=executable
          --all --as=output
      Display the executable file names of all test executables
      potentially affected by a change to the given file.
)";

int RunRefs(const std::vector<std::string>& args) {
  if (args.size() <= 1) {
    Err(Location(), "Unknown command format. See \"gn help refs\"",
        "Usage: \"gn refs <out_dir> (<label_pattern>|<file>)*\"")
        .PrintToStdout();
    return 1;
  }

  const base::CommandLine* cmdline = base::CommandLine::ForCurrentProcess();
  bool tree = cmdline->HasSwitch("tree");
  bool all = cmdline->HasSwitch("all");
  UniqueVector<HowTargetContainsFile> include_relations;
  for (const std::string& relation :
       cmdline->GetSwitchValueStrings("relation")) {
    if (relation == "source") {
      include_relations.push_back(HowTargetContainsFile::kSources);
    } else if (relation == "public") {
      include_relations.push_back(HowTargetContainsFile::kPublic);
    } else if (relation == "input") {
      include_relations.push_back(HowTargetContainsFile::kInputs);
    } else if (relation == "data") {
      include_relations.push_back(HowTargetContainsFile::kData);
    } else if (relation == "script") {
      include_relations.push_back(HowTargetContainsFile::kScript);
    } else if (relation == "output") {
      include_relations.push_back(HowTargetContainsFile::kOutput);
    } else {
      Err(Location(), "Unknown relation: " + relation).PrintToStdout();
      return 1;
    }
  }
  bool default_toolchain_only = cmdline->HasSwitch(switches::kDefaultToolchain);

  // Deliberately leaked to avoid expensive process teardown.
  Setup* setup = new Setup;
  if (!setup->DoSetup(args[0], false) || !setup->Run())
    return 1;

  // The inputs are everything but the first arg (which is the build dir).
  std::vector<std::string> inputs;
  for (size_t i = 1; i < args.size(); i++) {
    if (args[i][0] == '@') {
      // The argument is as a path to a response file.
      std::string contents;
      bool ret =
          base::ReadFileToString(UTF8ToFilePath(args[i].substr(1)), &contents);
      if (!ret) {
        Err(Location(), "Response file " + args[i].substr(1) + " not found.")
            .PrintToStdout();
        return 1;
      }
      for (const std::string& line : base::SplitString(
               contents, "\n", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL)) {
        if (!line.empty())
          inputs.push_back(line);
      }
    } else {
      // The argument is a label or a path.
      inputs.push_back(args[i]);
    }
  }

  // Get the matches for the command-line input.
  UniqueVector<const Target*> target_matches;
  UniqueVector<const Config*> config_matches;
  UniqueVector<const Toolchain*> toolchain_matches;
  UniqueVector<SourceFile> file_matches;
  if (!ResolveFromCommandLineInput(setup, inputs, default_toolchain_only,
                                   &target_matches, &config_matches,
                                   &toolchain_matches, &file_matches))
    return 1;

  // When you give a file or config as an input, you want the targets that are
  // associated with it. We don't want to just append this to the
  // target_matches, however, since these targets should actually be listed in
  // the output, while for normal targets you don't want to see the inputs,
  // only what refers to them.
  std::vector<const Target*> all_targets =
      setup->builder().GetAllResolvedTargets();
  UniqueVector<const Target*> explicit_target_matches;
  for (const auto& file : file_matches) {
    std::vector<TargetContainingFile> target_containing;
    GetTargetsContainingFile(setup, all_targets, file, default_toolchain_only,
                             &target_containing);

    // Extract just the Target*.
    for (const TargetContainingFile& pair : target_containing) {
      if (!include_relations.empty() &&
          !include_relations.Contains(pair.second)) {
        continue;
      }
      explicit_target_matches.push_back(pair.first);
    }
  }
  for (auto* config : config_matches) {
    GetTargetsReferencingConfig(setup, all_targets, config,
                                default_toolchain_only,
                                &explicit_target_matches);
  }

  // Tell the user if their input matches no files or labels. We need to check
  // both that it matched no targets and no configs. File input will already
  // have been converted to targets at this point. Configs will have been
  // converted to targets also, but there could be no targets referencing the
  // config, which is different than no config with that name.
  bool quiet = cmdline->HasSwitch("q");
  if (!quiet && config_matches.empty() && explicit_target_matches.empty() &&
      target_matches.empty()) {
    OutputString("The input matches no targets, configs, or files.\n",
                 DECORATION_YELLOW);
    return 1;
  }

  // Construct the reverse dependency tree.
  DepMap dep_map;
  FillDepMap(setup, &dep_map);

  size_t cnt = 0;
  if (tree)
    cnt = DoTreeOutput(dep_map, target_matches, explicit_target_matches, all);
  else if (all)
    cnt = DoAllListOutput(dep_map, target_matches, explicit_target_matches);
  else
    cnt = DoDirectListOutput(dep_map, target_matches, explicit_target_matches);

  // If you ask for the references of a valid target, but that target has
  // nothing referencing it, we'll get here without having printed anything.
  if (!quiet && cnt == 0)
    OutputString("Nothing references this.\n", DECORATION_YELLOW);

  return 0;
}

}  // namespace commands
