// 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 <mutex>

#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/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 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";

// Collects Ninja rules for each toolchain. The lock protectes the rules.
struct TargetWriteInfo {
  std::mutex lock;
  NinjaWriter::PerToolchainRules rules;
};

// Called on worker thread to write the ninja file.
void BackgroundDoWrite(TargetWriteInfo* write_info, const Target* target) {
  std::string rule = NinjaTargetWriter::RunAndWriteFile(target);
  DCHECK(!rule.empty());

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

// 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->GetSwitchValueASCII(kSwitchSln);
    std::string filters;
    if (command_line->HasSwitch(kSwitchFilters))
      filters = command_line->GetSwitchValueASCII(kSwitchFilters);
    std::string win_kit;
    if (command_line->HasSwitch(kSwitchIdeValueWinSdk))
      win_kit = command_line->GetSwitchValueASCII(kSwitchIdeValueWinSdk);
    std::string ninja_extra_args;
    if (command_line->HasSwitch(kSwitchNinjaExtraArgs)) {
      ninja_extra_args =
          command_line->GetSwitchValueASCII(kSwitchNinjaExtraArgs);
    }
    std::string ninja_executable;
    if (command_line->HasSwitch(kSwitchNinjaExecutable)) {
      ninja_executable =
          command_line->GetSwitchValueASCII(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->GetSwitchValueASCII(kSwitchXcodeProject),
        command_line->GetSwitchValueASCII(kSwitchIdeRootTarget),
        command_line->GetSwitchValueASCII(kSwitchNinjaExecutable),
        command_line->GetSwitchValueASCII(kSwitchFilters),
        command_line->GetSwitchValueASCII(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->GetSwitchValueASCII(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->GetSwitchValueASCII(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->GetSwitchValueASCII(kSwitchJsonFileName);
    if (file_name.empty())
      file_name = "project.json";
    std::string exec_script =
        command_line->GetSwitchValueASCII(kSwitchJsonIdeScript);
    std::string exec_script_extra_args =
        command_line->GetSwitchValueASCII(kSwitchJsonIdeScriptArgs);
    std::string filters = command_line->GetSwitchValueASCII(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_switch = command_line->HasSwitch(kSwitchExportCompileCommands);

  bool has_patterns = !setup.export_compile_commands().empty();
  if (!has_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);

  bool ok = true;
  if (has_switch) {
    // Legacy format using the command-line switch.
    std::string target_filters =
        command_line->GetSwitchValueASCII(kSwitchExportCompileCommands);
    ok = CompileCommandsWriter::RunAndWriteFilesLegacyFilters(
        &setup.build_settings(), setup.builder(), output_path, target_filters,
        err);
  } else {
    // Use the patterns from the .gn file.
    ok = CompileCommandsWriter::RunAndWriteFiles(
        &setup.build_settings(), setup.builder(), output_path,
        setup.export_compile_commands(), 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 file so the next ninja invocation will use the right mtime. 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 build.ninja 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"))};
    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 ommitted, 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 ommitted. 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 ommitted, 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 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.

  --export-compile-commands[=<target_name1,target_name2...>]
      Overrides the value of the export_compile_commands in the .gn file (see
      "gn help dotfile").

      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->GetSwitchValueASCII(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;
  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;

  // 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 (!WriteRuntimeDepsFilesIfNecessary(&setup->build_settings(),
                                        setup->builder(), &err)) {
    err.PrintToStdout();
    return 1;
  }

  if (!CheckForInvalidGeneratedInputs(setup))
    return 1;

  if (command_line->HasSwitch(kSwitchIde) &&
      !RunIdeWriter(command_line->GetSwitchValueASCII(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);
  }

  return 0;
}

}  // namespace commands
