// 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 <inttypes.h>

#include <mutex>
#include <thread>
#include <unordered_map>

#include "base/command_line.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "base/timer/elapsed_timer.h"
#include "gn/build_settings.h"
#include "gn/commands.h"
#include "gn/compile_commands_writer.h"
#include "gn/eclipse_writer.h"
#include "gn/filesystem_utils.h"
#include "gn/json_project_writer.h"
#include "gn/label_pattern.h"
#include "gn/ninja_outputs_writer.h"
#include "gn/ninja_target_writer.h"
#include "gn/ninja_tools.h"
#include "gn/ninja_writer.h"
#include "gn/qt_creator_writer.h"
#include "gn/runtime_deps.h"
#include "gn/rust_project_writer.h"
#include "gn/scheduler.h"
#include "gn/setup.h"
#include "gn/standard_out.h"
#include "gn/switches.h"
#include "gn/target.h"
#include "gn/visual_studio_writer.h"
#include "gn/xcode_writer.h"

namespace commands {

namespace {

const char kSwitchCheck[] = "check";
const char kSwitchCleanStale[] = "clean-stale";
const char kSwitchFilters[] = "filters";
const char kSwitchIde[] = "ide";
const char kSwitchIdeValueEclipse[] = "eclipse";
const char kSwitchIdeValueQtCreator[] = "qtcreator";
const char kSwitchIdeValueVs[] = "vs";
const char kSwitchIdeValueVs2013[] = "vs2013";
const char kSwitchIdeValueVs2015[] = "vs2015";
const char kSwitchIdeValueVs2017[] = "vs2017";
const char kSwitchIdeValueVs2019[] = "vs2019";
const char kSwitchIdeValueVs2022[] = "vs2022";
const char kSwitchIdeValueWinSdk[] = "winsdk";
const char kSwitchIdeValueXcode[] = "xcode";
const char kSwitchIdeValueJson[] = "json";
const char kSwitchIdeRootTarget[] = "ide-root-target";
const char kSwitchNinjaExecutable[] = "ninja-executable";
const char kSwitchNinjaExtraArgs[] = "ninja-extra-args";
const char kSwitchNinjaOutputsFile[] = "ninja-outputs-file";
const char kSwitchNinjaOutputsScript[] = "ninja-outputs-script";
const char kSwitchNinjaOutputsScriptArgs[] = "ninja-outputs-script-args";
const char kSwitchNoDeps[] = "no-deps";
const char kSwitchSln[] = "sln";
const char kSwitchXcodeProject[] = "xcode-project";
const char kSwitchXcodeBuildSystem[] = "xcode-build-system";
const char kSwitchXcodeBuildsystemValueLegacy[] = "legacy";
const char kSwitchXcodeBuildsystemValueNew[] = "new";
const char kSwitchXcodeConfigurations[] = "xcode-configs";
const char kSwitchXcodeConfigurationBuildPath[] = "xcode-config-build-dir";
const char kSwitchXcodeAdditionalFilesPatterns[] =
    "xcode-additional-files-patterns";
const char kSwitchXcodeAdditionalFilesRoots[] = "xcode-additional-files-roots";
const char kSwitchJsonFileName[] = "json-file-name";
const char kSwitchJsonIdeScript[] = "json-ide-script";
const char kSwitchJsonIdeScriptArgs[] = "json-ide-script-args";
const char kSwitchExportCompileCommands[] = "export-compile-commands";
const char kSwitchExportRustProject[] = "export-rust-project";

// A map type used to implement --ide=ninja_outputs
using NinjaOutputsMap = NinjaOutputsWriter::MapType;

// Collects Ninja rules for each toolchain. The lock protects the rules
struct TargetWriteInfo {
  // Set this to true to populate |ninja_outputs_map| below.
  bool want_ninja_outputs = false;

  std::mutex lock;
  NinjaWriter::PerToolchainRules rules;

  NinjaOutputsMap ninja_outputs_map;

  using ResolvedMap = std::unordered_map<std::thread::id, ResolvedTargetData>;
  std::unique_ptr<ResolvedMap> resolved_map = std::make_unique<ResolvedMap>();

  void LeakOnPurpose() { (void)resolved_map.release(); }
};

// Called on worker thread to write the ninja file.
void BackgroundDoWrite(TargetWriteInfo* write_info, const Target* target) {
  ResolvedTargetData* resolved;
  std::vector<OutputFile> target_ninja_outputs;
  std::vector<OutputFile>* ninja_outputs =
      write_info->want_ninja_outputs ? &target_ninja_outputs : nullptr;

  {
    std::lock_guard<std::mutex> lock(write_info->lock);
    resolved = &((*write_info->resolved_map)[std::this_thread::get_id()]);
  }
  std::string rule =
      NinjaTargetWriter::RunAndWriteFile(target, resolved, ninja_outputs);

  DCHECK(!rule.empty());

  {
    std::lock_guard<std::mutex> lock(write_info->lock);
    write_info->rules[target->toolchain()].emplace_back(target,
                                                        std::move(rule));

    if (write_info->want_ninja_outputs) {
      write_info->ninja_outputs_map.emplace(target,
                                            std::move(target_ninja_outputs));
    }
  }
}

// Called on the main thread.
void ItemResolvedAndGeneratedCallback(TargetWriteInfo* write_info,
                                      const BuilderRecord* record) {
  const Item* item = record->item();
  const Target* target = item->AsTarget();
  if (target) {
    g_scheduler->ScheduleWork(
        [write_info, target]() { BackgroundDoWrite(write_info, target); });
  }
}

// Returns a pointer to the target with the given file as an output, or null
// if no targets generate the file. This is brute force since this is an
// error condition and performance shouldn't matter.
const Target* FindTargetThatGeneratesFile(const Builder& builder,
                                          const SourceFile& file) {
  std::vector<const Target*> targets = builder.GetAllResolvedTargets();
  if (targets.empty())
    return nullptr;

  OutputFile output_file(targets[0]->settings()->build_settings(), file);
  for (const Target* target : targets) {
    for (const auto& cur_output : target->computed_outputs()) {
      if (cur_output == output_file)
        return target;
    }
  }
  return nullptr;
}

// Prints an error that the given file was present as a source or input in
// the given target(s) but was not generated by any of its dependencies.
void PrintInvalidGeneratedInput(const Builder& builder,
                                const SourceFile& file,
                                const std::vector<const Target*>& targets) {
  std::string err;

  // Only show the toolchain labels (which can be confusing) if something
  // isn't the default.
  bool show_toolchains = false;
  const Label& default_toolchain =
      targets[0]->settings()->default_toolchain_label();
  for (const Target* target : targets) {
    if (target->settings()->toolchain_label() != default_toolchain) {
      show_toolchains = true;
      break;
    }
  }

  const Target* generator = FindTargetThatGeneratesFile(builder, file);
  if (generator &&
      generator->settings()->toolchain_label() != default_toolchain)
    show_toolchains = true;

  const std::string target_str = targets.size() > 1 ? "targets" : "target";
  err += "The file:\n";
  err += "  " + file.value() + "\n";
  err += "is listed as an input or source for the " + target_str + ":\n";
  for (const Target* target : targets)
    err += "  " + target->label().GetUserVisibleName(show_toolchains) + "\n";

  if (generator) {
    err += "but this file was not generated by any dependencies of the " +
           target_str + ". The target\nthat generates the file is:\n  ";
    err += generator->label().GetUserVisibleName(show_toolchains);
  } else {
    err += "but no targets in the build generate that file.";
  }

  Err(Location(), "Input to " + target_str + " not generated by a dependency.",
      err)
      .PrintToStdout();
}

bool CheckForInvalidGeneratedInputs(Setup* setup) {
  std::multimap<SourceFile, const Target*> unknown_inputs =
      g_scheduler->GetUnknownGeneratedInputs();
  if (unknown_inputs.empty())
    return true;  // No bad files.

  int errors_found = 0;
  auto cur = unknown_inputs.begin();
  while (cur != unknown_inputs.end()) {
    errors_found++;
    auto end_of_range = unknown_inputs.upper_bound(cur->first);

    // Package the values more conveniently for printing.
    SourceFile bad_input = cur->first;
    std::vector<const Target*> targets;
    while (cur != end_of_range)
      targets.push_back((cur++)->second);

    PrintInvalidGeneratedInput(setup->builder(), bad_input, targets);
    OutputString("\n");
  }

  OutputString(
      "If you have generated inputs, there needs to be a dependency path "
      "between the\ntwo targets in addition to just listing the files. For "
      "indirect dependencies,\nthe intermediate ones must be public_deps. "
      "data_deps don't count since they're\nonly runtime dependencies. If "
      "you think a dependency chain exists, it might be\nbecause the chain "
      "is private. Try \"gn path\" to analyze.\n");

  if (errors_found > 1) {
    OutputString(base::StringPrintf("\n%d generated input errors found.\n",
                                    errors_found),
                 DECORATION_YELLOW);
  }
  return false;
}

bool RunIdeWriter(const std::string& ide,
                  const BuildSettings* build_settings,
                  const Builder& builder,
                  Err* err) {
  const base::CommandLine* command_line =
      base::CommandLine::ForCurrentProcess();
  bool quiet = command_line->HasSwitch(switches::kQuiet);
  base::ElapsedTimer timer;

  if (ide == kSwitchIdeValueEclipse) {
    bool res = EclipseWriter::RunAndWriteFile(build_settings, builder, err);
    if (res && !quiet) {
      OutputString("Generating Eclipse settings took " +
                   base::Int64ToString(timer.Elapsed().InMilliseconds()) +
                   "ms\n");
    }
    return res;
  } else if (ide == kSwitchIdeValueVs || ide == kSwitchIdeValueVs2013 ||
             ide == kSwitchIdeValueVs2015 || ide == kSwitchIdeValueVs2017 ||
             ide == kSwitchIdeValueVs2019 || ide == kSwitchIdeValueVs2022) {
    VisualStudioWriter::Version version = VisualStudioWriter::Version::Vs2019;
    if (ide == kSwitchIdeValueVs2013)
      version = VisualStudioWriter::Version::Vs2013;
    else if (ide == kSwitchIdeValueVs2015)
      version = VisualStudioWriter::Version::Vs2015;
    else if (ide == kSwitchIdeValueVs2017)
      version = VisualStudioWriter::Version::Vs2017;
    else if (ide == kSwitchIdeValueVs2022)
      version = VisualStudioWriter::Version::Vs2022;

    std::string sln_name;
    if (command_line->HasSwitch(kSwitchSln))
      sln_name = command_line->GetSwitchValueString(kSwitchSln);
    std::string filters;
    if (command_line->HasSwitch(kSwitchFilters))
      filters = command_line->GetSwitchValueString(kSwitchFilters);
    std::string win_kit;
    if (command_line->HasSwitch(kSwitchIdeValueWinSdk))
      win_kit = command_line->GetSwitchValueString(kSwitchIdeValueWinSdk);
    std::string ninja_extra_args;
    if (command_line->HasSwitch(kSwitchNinjaExtraArgs)) {
      ninja_extra_args =
          command_line->GetSwitchValueString(kSwitchNinjaExtraArgs);
    }
    std::string ninja_executable;
    if (command_line->HasSwitch(kSwitchNinjaExecutable)) {
      ninja_executable =
          command_line->GetSwitchValueString(kSwitchNinjaExecutable);
    }
    bool no_deps = command_line->HasSwitch(kSwitchNoDeps);
    bool res = VisualStudioWriter::RunAndWriteFiles(
        build_settings, builder, version, sln_name, filters, win_kit,
        ninja_extra_args, ninja_executable, no_deps, err);
    if (res && !quiet) {
      OutputString("Generating Visual Studio projects took " +
                   base::Int64ToString(timer.Elapsed().InMilliseconds()) +
                   "ms\n");
    }
    return res;
  } else if (ide == kSwitchIdeValueXcode) {
    XcodeWriter::Options options = {
        command_line->GetSwitchValueString(kSwitchXcodeProject),
        command_line->GetSwitchValueString(kSwitchIdeRootTarget),
        command_line->GetSwitchValueString(kSwitchNinjaExecutable),
        command_line->GetSwitchValueString(kSwitchFilters),
        command_line->GetSwitchValueString(kSwitchXcodeConfigurations),
        command_line->GetSwitchValuePath(kSwitchXcodeConfigurationBuildPath),
        command_line->GetSwitchValueNative(kSwitchXcodeAdditionalFilesPatterns),
        command_line->GetSwitchValueNative(kSwitchXcodeAdditionalFilesRoots),
        XcodeBuildSystem::kLegacy,
    };

    if (options.project_name.empty()) {
      options.project_name = "all";
    }

    const std::string build_system =
        command_line->GetSwitchValueString(kSwitchXcodeBuildSystem);
    if (!build_system.empty()) {
      if (build_system == kSwitchXcodeBuildsystemValueNew) {
        options.build_system = XcodeBuildSystem::kNew;
      } else if (build_system == kSwitchXcodeBuildsystemValueLegacy) {
        options.build_system = XcodeBuildSystem::kLegacy;
      } else {
        *err = Err(Location(), "Unknown build system: " + build_system);
        return false;
      }
    }

    bool res =
        XcodeWriter::RunAndWriteFiles(build_settings, builder, options, err);
    if (res && !quiet) {
      OutputString("Generating Xcode projects took " +
                   base::Int64ToString(timer.Elapsed().InMilliseconds()) +
                   "ms\n");
    }
    return res;
  } else if (ide == kSwitchIdeValueQtCreator) {
    std::string root_target;
    if (command_line->HasSwitch(kSwitchIdeRootTarget))
      root_target = command_line->GetSwitchValueString(kSwitchIdeRootTarget);
    bool res = QtCreatorWriter::RunAndWriteFile(build_settings, builder, err,
                                                root_target);
    if (res && !quiet) {
      OutputString("Generating QtCreator projects took " +
                   base::Int64ToString(timer.Elapsed().InMilliseconds()) +
                   "ms\n");
    }
    return res;
  } else if (ide == kSwitchIdeValueJson) {
    std::string file_name =
        command_line->GetSwitchValueString(kSwitchJsonFileName);
    if (file_name.empty())
      file_name = "project.json";
    std::string exec_script =
        command_line->GetSwitchValueString(kSwitchJsonIdeScript);
    std::string exec_script_extra_args =
        command_line->GetSwitchValueString(kSwitchJsonIdeScriptArgs);
    std::string filters = command_line->GetSwitchValueString(kSwitchFilters);

    bool res = JSONProjectWriter::RunAndWriteFiles(
        build_settings, builder, file_name, exec_script, exec_script_extra_args,
        filters, quiet, err);
    if (res && !quiet) {
      OutputString("Generating JSON projects took " +
                   base::Int64ToString(timer.Elapsed().InMilliseconds()) +
                   "ms\n");
    }
    return res;
  }

  *err = Err(Location(), "Unknown IDE: " + ide);
  return false;
}

bool RunRustProjectWriter(const BuildSettings* build_settings,
                          const Builder& builder,
                          Err* err) {
  const base::CommandLine* command_line =
      base::CommandLine::ForCurrentProcess();
  bool quiet = command_line->HasSwitch(switches::kQuiet);
  base::ElapsedTimer timer;

  std::string file_name = "rust-project.json";
  bool res = RustProjectWriter::RunAndWriteFiles(build_settings, builder,
                                                 file_name, quiet, err);
  if (res && !quiet) {
    OutputString("Generating rust-project.json took " +
                 base::Int64ToString(timer.Elapsed().InMilliseconds()) +
                 "ms\n");
  }
  return res;
}

bool RunCompileCommandsWriter(Setup& setup, Err* err) {
  // The compilation database is written if either the .gn setting is set or if
  // the command line flag is set. The command line flag takes precedence.
  const base::CommandLine* command_line =
      base::CommandLine::ForCurrentProcess();
  bool has_legacy_switch =
      command_line->HasSwitch(kSwitchExportCompileCommands);

  bool has_patterns = !setup.export_compile_commands().empty();
  if (!has_legacy_switch && !has_patterns)
    return true;  // No compilation database needs to be written.

  bool quiet = command_line->HasSwitch(switches::kQuiet);
  base::ElapsedTimer timer;

  // The compilation database file goes in the build directory.
  SourceFile output_file =
      setup.build_settings().build_dir().ResolveRelativeFile(
          Value(nullptr, "compile_commands.json"), err);
  if (output_file.is_null())
    return false;
  base::FilePath output_path = setup.build_settings().GetFullPath(output_file);

  std::optional<std::string> legacy_target_filters;
  if (has_legacy_switch) {
    legacy_target_filters =
        command_line->GetSwitchValueString(kSwitchExportCompileCommands);
  }

  bool ok = CompileCommandsWriter::RunAndWriteFiles(
      &setup.build_settings(), setup.builder().GetAllResolvedTargets(),
      setup.export_compile_commands(), legacy_target_filters, output_path, err);
  if (ok && !quiet) {
    OutputString("Generating compile_commands took " +
                 base::Int64ToString(timer.Elapsed().InMilliseconds()) +
                 "ms\n");
  }
  return ok;
}

bool RunNinjaPostProcessTools(const BuildSettings* build_settings,
                              base::FilePath ninja_executable,
                              bool is_regeneration,
                              bool clean_stale,
                              Err* err) {
  // If the user did not specify an executable, skip running the post processing
  // tools. Since these tools can re-write ninja build log and dep logs, it is
  // really important that ninja executable used for tools matches the
  // executable that is used for builds.
  if (ninja_executable.empty()) {
    if (clean_stale) {
      *err = Err(Location(), "No --ninja-executable provided.",
                 "--clean-stale requires a ninja executable to run. You can "
                 "provide one on the command line via --ninja-executable.");
      return false;
    }

    return true;
  }

  base::FilePath build_dir =
      build_settings->GetFullPath(build_settings->build_dir());

  if (clean_stale) {
    if (build_settings->ninja_required_version() < Version{1, 10, 0}) {
      *err = Err(Location(), "Need a ninja executable at least version 1.10.0.",
                 "--clean-stale requires a ninja executable of version 1.10.0 "
                 "or later.");
      return false;
    }

    if (!InvokeNinjaCleanDeadTool(ninja_executable, build_dir, err)) {
      return false;
    }

    if (!InvokeNinjaRecompactTool(ninja_executable, build_dir, err)) {
      return false;
    }
  }

  // If we have a ninja version that supports restat, we should restat the
  // build.ninja or build.ninja.stamp files so the next ninja invocation
  // will use the right mtimes. If gen is being invoked as part of a re-gen
  // (ie, ninja is invoking gn gen), then we can elide this restat, as
  // ninja will restat the appropriate file anyways after it is complete.
  if (!is_regeneration &&
      build_settings->ninja_required_version() >= Version{1, 10, 0}) {
    std::vector<base::FilePath> files_to_restat{
        base::FilePath(FILE_PATH_LITERAL("build.ninja")),
        base::FilePath(FILE_PATH_LITERAL("build.ninja.stamp")),
    };
    if (!InvokeNinjaRestatTool(ninja_executable, build_dir, files_to_restat,
                               err)) {
      return false;
    }
  }
  return true;
}

}  // namespace

const char kGen[] = "gen";
const char kGen_HelpShort[] = "gen: Generate ninja files.";
const char kGen_Help[] =
    R"(gn gen [--check] [<ide options>] <out_dir>

  Generates ninja files from the current tree and puts them in the given output
  directory.

  The output directory can be a source-repo-absolute path name such as:
      //out/foo
  Or it can be a directory relative to the current directory such as:
      out/foo

  "gn gen --check" is the same as running "gn check". "gn gen --check=system" is
  the same as running "gn check --check-system".  See "gn help check" for
  documentation on that mode.

  See "gn help switches" for the common command-line switches.

General options

  --ninja-executable=<string>
      Can be used to specify the ninja executable to use. This executable will
      be used as an IDE option to indicate which ninja to use for building. This
      executable will also be used as part of the gen process for triggering a
      restat on generated ninja files and for use with --clean-stale.

  --clean-stale
      This option will cause no longer needed output files to be removed from
      the build directory, and their records pruned from the ninja build log and
      dependency database after the ninja build graph has been generated. This
      option requires a ninja executable of at least version 1.10.0. It can be
      provided by the --ninja-executable switch. Also see "gn help clean_stale".

IDE options

  GN optionally generates files for IDE. Files won't be overwritten if their
  contents don't change. Possibilities for <ide options>

  --ide=<ide_name>
      Generate files for an IDE. Currently supported values:
      "eclipse" - Eclipse CDT settings file.
      "vs" - Visual Studio project/solution files.
             (default Visual Studio version: 2019)
      "vs2013" - Visual Studio 2013 project/solution files.
      "vs2015" - Visual Studio 2015 project/solution files.
      "vs2017" - Visual Studio 2017 project/solution files.
      "vs2019" - Visual Studio 2019 project/solution files.
      "vs2022" - Visual Studio 2022 project/solution files.
      "xcode" - Xcode workspace/solution files.
      "qtcreator" - QtCreator project files.
      "json" - JSON file containing target information

  --filters=<path_prefixes>
      Semicolon-separated list of label patterns used to limit the set of
      generated projects (see "gn help label_pattern"). Only matching targets
      and their dependencies will be included in the solution. Only used for
      Visual Studio, Xcode and JSON.

Visual Studio Flags

  --sln=<file_name>
      Override default sln file name ("all"). Solution file is written to the
      root build directory.

  --no-deps
      Don't include targets dependencies to the solution. Changes the way how
      --filters option works. Only directly matching targets are included.

  --winsdk=<sdk_version>
      Use the specified Windows 10 SDK version to generate project files.
      As an example, "10.0.15063.0" can be specified to use Creators Update SDK
      instead of the default one.

  --ninja-executable=<string>
      Can be used to specify the ninja executable to use when building.

  --ninja-extra-args=<string>
      This string is passed without any quoting to the ninja invocation
      command-line. Can be used to configure ninja flags, like "-j".

Xcode Flags

  --xcode-project=<file_name>
      Override default Xcode project file name ("all"). The project file is
      written to the root build directory.

  --xcode-build-system=<value>
      Configure the build system to use for the Xcode project. Supported
      values are (default to "legacy"):
      "legacy" - Legacy Build system
      "new" - New Build System

  --xcode-configs=<config_name_list>
      Configure the list of build configuration supported by the generated
      project. If specified, must be a list of semicolon-separated strings.
      If omitted, a single configuration will be used in the generated
      project derived from the build directory.

  --xcode-config-build-dir=<string>
      If present, must be a path relative to the source directory. It will
      default to $root_out_dir if omitted. The path is assumed to point to
      the directory where ninja needs to be invoked. This variable can be
      used to build for multiple configuration / platform / environment from
      the same generated Xcode project (assuming that the user has created a
      gn build directory with the correct args.gn for each).

      One useful value is to use Xcode variables such as '${CONFIGURATION}'
      or '${EFFECTIVE_PLATFORM}'.

  --xcode-additional-files-patterns=<pattern_list>
      If present, must be a list of semicolon-separated file patterns. It
      will be used to add all files matching the pattern located in the
      source tree to the project. It can be used to add, e.g. documentation
      files to the project to allow easily edit them.

  --xcode-additional-files-roots=<path_list>
      If present, must be a list of semicolon-separated paths. It will be used
      as roots when looking for additional files to add. If omitted, defaults
      to "//".

  --ninja-executable=<string>
      Can be used to specify the ninja executable to use when building.

  --ninja-extra-args=<string>
      This string is passed without any quoting to the ninja invocation
      command-line. Can be used to configure ninja flags, like "-j".

  --ide-root-target=<target_name>
      Name of the target corresponding to "All" target in Xcode. If unset,
      "All" invokes ninja without any target and builds everything.

QtCreator Flags

  --ide-root-target=<target_name>
      Name of the root target for which the QtCreator project will be generated
      to contain files of it and its dependencies. If unset, the whole build
      graph will be emitted.


Eclipse IDE Support

  GN DOES NOT generate Eclipse CDT projects. Instead, it generates a settings
  file which can be imported into an Eclipse CDT project. The XML file contains
  a list of include paths and defines. Because GN does not generate a full
  .cproject definition, it is not possible to properly define includes/defines
  for each file individually. Instead, one set of includes/defines is generated
  for the entire project. This works fairly well but may still result in a few
  indexer issues here and there.

Generic JSON Output

  Dumps target information to a JSON file and optionally invokes a
  python script on the generated file. See the comments at the beginning
  of json_project_writer.cc and desc_builder.cc for an overview of the JSON
  file format.

  --json-file-name=<json_file_name>
      Overrides default file name (project.json) of generated JSON file.

  --json-ide-script=<path_to_python_script>
      Executes python script after the JSON file is generated or updated with
      new content. Path can be project absolute (//), system absolute (/) or
      relative, in which case the output directory will be base. Path to
      generated JSON file will be first argument when invoking script.

  --json-ide-script-args=<argument>
      Optional second argument that will be passed to executed script.

Ninja Outputs

  The --ninja-outputs-file=<FILE> option dumps a JSON file that maps GN labels
  to their Ninja output paths. This can be later processed to build an index
  to convert between Ninja targets and GN ones before or after the build itself.
  It looks like:

    {
      "label1": [
        "path1",
        "path2"
      ],
      "label2": [
        "path3"
      ]
    }

  --ninja-outputs-script=<path_to_python_script>
    Executes python script after the outputs file is generated or updated
    with new content. Path can be project absolute (//), system absolute (/) or
    relative, in which case the output directory will be base. Path to
    generated file will be first argument when invoking script.

  --ninja-outputs-script-args=<argument>
    Optional second argument that will be passed to executed script.

Compilation Database

  --export-rust-project
      Produces a rust-project.json file in the root of the build directory
      This is used for various tools in the Rust ecosystem allowing for the
      replay of individual compilations independent of the build system.
      This is an unstable format and likely to change without warning.

  --add-export-compile-commands=<label_pattern>
      Adds an additional label pattern (see "gn help label_pattern") of a
      target to add to the compilation database. This pattern is appended to any
      list values specified in the export_compile_commands variable in the
      .gn file (see "gn help dotfile"). This allows the user to add additional
      targets to the compilation database that the project doesn't add by default.

      To add more than one value, specify this switch more than once. Each
      invocation adds an additional label pattern.

      Example:
        --add-export-compile-commands=//tools:my_tool
        --add-export-compile-commands="//base/*"

  --export-compile-commands[=<target_name1,target_name2...>]
      DEPRECATED https://bugs.chromium.org/p/gn/issues/detail?id=302.
      Please use --add-export-compile-commands for per-user configuration, and
      the "export_compile_commands" value in the project-level .gn file (see
      "gn help dotfile") for per-project configuration.

      Overrides the value of the export_compile_commands in the .gn file (see
      "gn help dotfile") as well as the --add-export-compile-commands switch.

      Unlike the .gn setting, this switch takes a legacy format which is a list
      of target names that are matched in any directory. For example, "foo" will
      match:
       - "//path/to/src:foo"
       - "//other/path:foo"
       - "//foo:foo"
      and not match:
       - "//foo:bar"
)";

int RunGen(const std::vector<std::string>& args) {
  base::ElapsedTimer timer;

  if (args.size() != 1) {
    Err(Location(), "Need exactly one build directory to generate.",
        "I expected something more like \"gn gen out/foo\"\n"
        "You can also see \"gn help gen\".")
        .PrintToStdout();
    return 1;
  }

  // Deliberately leaked to avoid expensive process teardown.
  Setup* setup = new Setup();
  // Generate an empty args.gn file if it does not exists
  if (!base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kArgs)) {
    setup->set_gen_empty_args(true);
  }
  if (!setup->DoSetup(args[0], true))
    return 1;

  const base::CommandLine* command_line =
      base::CommandLine::ForCurrentProcess();
  if (command_line->HasSwitch(kSwitchCheck)) {
    setup->set_check_public_headers(true);
    if (command_line->GetSwitchValueString(kSwitchCheck) == "system")
      setup->set_check_system_includes(true);
  }

  // If this is a regeneration, replace existing build.ninja and build.ninja.d
  // with just enough for ninja to call GN and regenerate ninja files. This
  // removes any potential soon-to-be-dangling references and ensures that
  // regeneration can be restarted if interrupted.
  if (command_line->HasSwitch(switches::kRegeneration)) {
    if (!commands::PrepareForRegeneration(&setup->build_settings())) {
      return false;
    }
  }

  // Cause the load to also generate the ninja files for each target.
  TargetWriteInfo write_info;
  write_info.want_ninja_outputs =
      command_line->HasSwitch(kSwitchNinjaOutputsFile);

  setup->builder().set_resolved_and_generated_callback(
      [&write_info](const BuilderRecord* record) {
        ItemResolvedAndGeneratedCallback(&write_info, record);
      });

  // Do the actual load. This will also write out the target ninja files.
  if (!setup->Run())
    return 1;

  if (command_line->HasSwitch(switches::kVerbose))
    OutputString("Build graph constructed in " +
                 base::Int64ToString(timer.Elapsed().InMilliseconds()) +
                 "ms\n");

  // Sort the targets in each toolchain according to their label. This makes
  // the ninja files have deterministic content.
  for (auto& cur_toolchain : write_info.rules) {
    std::sort(cur_toolchain.second.begin(), cur_toolchain.second.end(),
              [](const NinjaWriter::TargetRulePair& a,
                 const NinjaWriter::TargetRulePair& b) {
                return a.first->label() < b.first->label();
              });
  }

  Err err;
  // Write the root ninja files.
  if (!NinjaWriter::RunAndWriteFiles(&setup->build_settings(), setup->builder(),
                                     write_info.rules, &err)) {
    err.PrintToStdout();
    return 1;
  }

  if (!RunNinjaPostProcessTools(
          &setup->build_settings(),
          command_line->GetSwitchValuePath(switches::kNinjaExecutable),
          command_line->HasSwitch(switches::kRegeneration),
          command_line->HasSwitch(kSwitchCleanStale), &err)) {
    err.PrintToStdout();
    return 1;
  }

  if (write_info.want_ninja_outputs) {
    ElapsedTimer outputs_timer;
    std::string file_name =
        command_line->GetSwitchValueString(kSwitchNinjaOutputsFile);
    if (file_name.empty()) {
      Err(Location(), "The --ninja-outputs-file argument cannot be empty!")
          .PrintToStdout();
      return 1;
    }

    bool quiet = command_line->HasSwitch(switches::kQuiet);

    std::string exec_script =
        command_line->GetSwitchValueString(kSwitchNinjaOutputsScript);

    std::string exec_script_extra_args =
        command_line->GetSwitchValueString(kSwitchNinjaOutputsScriptArgs);

    bool res = NinjaOutputsWriter::RunAndWriteFiles(
        write_info.ninja_outputs_map, &setup->build_settings(), file_name,
        exec_script, exec_script_extra_args, quiet, &err);
    if (!res) {
      err.PrintToStdout();
      return 1;
    }
    if (!command_line->HasSwitch(switches::kQuiet)) {
      OutputString(base::StringPrintf(
          "Generating Ninja outputs file took %" PRId64 "ms\n",
          outputs_timer.Elapsed().InMilliseconds()));
    }
  }

  if (!WriteRuntimeDepsFilesIfNecessary(&setup->build_settings(),
                                        setup->builder(), &err)) {
    err.PrintToStdout();
    return 1;
  }

  if (!CheckForInvalidGeneratedInputs(setup))
    return 1;

  if (command_line->HasSwitch(kSwitchIde) &&
      !RunIdeWriter(command_line->GetSwitchValueString(kSwitchIde),
                    &setup->build_settings(), setup->builder(), &err)) {
    err.PrintToStdout();
    return 1;
  }

  if (!RunCompileCommandsWriter(*setup, &err)) {
    err.PrintToStdout();
    return 1;
  }

  if (command_line->HasSwitch(kSwitchExportRustProject) &&
      !RunRustProjectWriter(&setup->build_settings(), setup->builder(), &err)) {
    err.PrintToStdout();
    return 1;
  }

  TickDelta elapsed_time = timer.Elapsed();

  if (!command_line->HasSwitch(switches::kQuiet)) {
    OutputString("Done. ", DECORATION_GREEN);

    size_t targets_collected = 0;
    for (const auto& rules : write_info.rules)
      targets_collected += rules.second.size();

    std::string stats =
        "Made " + base::NumberToString(targets_collected) + " targets from " +
        base::IntToString(
            setup->scheduler().input_file_manager()->GetInputFileCount()) +
        " files in " + base::Int64ToString(elapsed_time.InMilliseconds()) +
        "ms\n";
    OutputString(stats);
  }

  // Just like the build graph, leak the resolved data to avoid expensive
  // process teardown here too.
  write_info.LeakOnPurpose();

  return 0;
}

}  // namespace commands
