// 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 "gn/ninja_action_target_writer.h"

#include <stddef.h>

#include "base/strings/string_util.h"
#include "gn/deps_iterator.h"
#include "gn/err.h"
#include "gn/general_tool.h"
#include "gn/pool.h"
#include "gn/settings.h"
#include "gn/string_utils.h"
#include "gn/substitution_writer.h"
#include "gn/target.h"

NinjaActionTargetWriter::NinjaActionTargetWriter(const Target* target,
                                                 std::ostream& out)
    : NinjaTargetWriter(target, out),
      path_output_no_escaping_(
          target->settings()->build_settings()->build_dir(),
          target->settings()->build_settings()->root_path_utf8(),
          ESCAPE_NONE) {}

NinjaActionTargetWriter::~NinjaActionTargetWriter() = default;

void NinjaActionTargetWriter::Run() {
  std::string custom_rule_name = WriteRuleDefinition();

  // Collect our deps to pass as additional "hard dependencies" for input deps.
  // This will force all of the action's dependencies to be completed before
  // the action is run. Usually, if an action has a dependency, it will be
  // operating on the result of that previous step, so we need to be sure to
  // serialize these.
  std::vector<const Target*> additional_hard_deps;
  std::vector<OutputFile> data_outs;
  for (const auto& pair : target_->GetDeps(Target::DEPS_LINKED)) {
    if (pair.ptr->IsDataOnly()) {
      data_outs.push_back(pair.ptr->dependency_output_file());
    } else {
      additional_hard_deps.push_back(pair.ptr);
    }
  }

  // For ACTIONs, the input deps appear only once in the generated ninja
  // file, so WriteInputDepsStampAndGetDep() won't create a stamp file
  // and the action will just depend on all the input deps directly.
  size_t num_stamp_uses =
      target_->output_type() == Target::ACTION ? 1u : target_->sources().size();
  std::vector<OutputFile> input_deps =
      WriteInputDepsStampAndGetDep(additional_hard_deps, num_stamp_uses);
  out_ << std::endl;

  // Collects all output files for writing below.
  std::vector<OutputFile> output_files;

  if (target_->output_type() == Target::ACTION_FOREACH) {
    // Write separate build lines for each input source file.
    WriteSourceRules(custom_rule_name, input_deps, &output_files);
  } else {
    DCHECK(target_->output_type() == Target::ACTION);

    // Write a rule that invokes the script once with the outputs as outputs,
    // and the data as inputs. It does not depend on the sources.
    out_ << "build";
    SubstitutionWriter::GetListAsOutputFiles(
        settings_, target_->action_values().outputs(), &output_files);
    path_output_.WriteFiles(out_, output_files);

    out_ << ": " << custom_rule_name;
    if (!input_deps.empty()) {
      // As in WriteSourceRules, we want to force this target to rebuild any
      // time any of its dependencies change.
      out_ << " |";
      path_output_.WriteFiles(out_, input_deps);
    }
    out_ << std::endl;
    if (target_->action_values().has_depfile()) {
      WriteDepfile(SourceFile());
    }

    WriteNinjaVariablesForAction();

    if (target_->action_values().pool().ptr) {
      out_ << "  pool = ";
      out_ << target_->action_values().pool().ptr->GetNinjaName(
          settings_->default_toolchain_label());
      out_ << std::endl;
    }
  }
  out_ << std::endl;

  // Write the stamp, which also depends on all data deps. These are needed at
  // runtime and should be compiled when the action is, but don't need to be
  // done before we run the action.
  // TODO(thakis): If the action has just a single output, make things depend
  // on that output directly without writing a stamp file.
  for (const auto& dep : target_->data_deps())
    data_outs.push_back(dep.ptr->dependency_output_file());
  WriteStampForTarget(output_files, data_outs);
}

std::string NinjaActionTargetWriter::WriteRuleDefinition() {
  // Make a unique name for this rule.
  //
  // Use a unique name for the response file when there are multiple build
  // steps so that they don't stomp on each other. When there are no sources,
  // there will be only one invocation so we can use a simple name.
  std::string target_label = target_->label().GetUserVisibleName(true);
  std::string custom_rule_name(target_label);
  base::ReplaceChars(custom_rule_name, ":/()", "_", &custom_rule_name);
  custom_rule_name.append("_rule");

  const SubstitutionList& args = target_->action_values().args();
  EscapeOptions args_escape_options;
  args_escape_options.mode = ESCAPE_NINJA_COMMAND;

  out_ << "rule " << custom_rule_name << std::endl;

  if (target_->action_values().uses_rsp_file()) {
    // Needs a response file. The unique_name part is for action_foreach so
    // each invocation of the rule gets a different response file. This isn't
    // strictly necessary for regular one-shot actions, but it's easier to
    // just always define unique_name.
    std::string rspfile = custom_rule_name;
    if (!target_->sources().empty())
      rspfile += ".$unique_name";
    rspfile += ".rsp";
    out_ << "  rspfile = " << rspfile << std::endl;

    // Response file contents.
    out_ << "  rspfile_content =";
    for (const auto& arg :
         target_->action_values().rsp_file_contents().list()) {
      out_ << " ";
      SubstitutionWriter::WriteWithNinjaVariables(arg, args_escape_options,
                                                  out_);
    }
    out_ << std::endl;
  }

  out_ << "  command = ";
  path_output_.WriteFile(out_, settings_->build_settings()->python_path());
  out_ << " ";
  path_output_.WriteFile(out_, target_->action_values().script());
  for (const auto& arg : args.list()) {
    out_ << " ";
    SubstitutionWriter::WriteWithNinjaVariables(arg, args_escape_options, out_);
  }
  out_ << std::endl;
  out_ << "  description = ACTION " << target_label << std::endl;
  out_ << "  restat = 1" << std::endl;
  const Tool* tool =
      target_->toolchain()->GetTool(GeneralTool::kGeneralToolAction);
  if (tool && tool->pool().ptr) {
    out_ << "  pool = ";
    out_ << tool->pool().ptr->GetNinjaName(
        settings_->default_toolchain_label());
    out_ << std::endl;
  }

  return custom_rule_name;
}

void NinjaActionTargetWriter::WriteSourceRules(
    const std::string& custom_rule_name,
    const std::vector<OutputFile>& input_deps,
    std::vector<OutputFile>* output_files) {
  EscapeOptions args_escape_options;
  args_escape_options.mode = ESCAPE_NINJA_COMMAND;
  // We're writing the substitution values, these should not be quoted since
  // they will get pasted into the real command line.
  args_escape_options.inhibit_quoting = true;

  const Target::FileList& sources = target_->sources();
  for (size_t i = 0; i < sources.size(); i++) {
    out_ << "build";
    WriteOutputFilesForBuildLine(sources[i], output_files);

    out_ << ": " << custom_rule_name << " ";
    path_output_.WriteFile(out_, sources[i]);
    if (!input_deps.empty()) {
      // Using "|" for the dependencies forces all implicit dependencies to be
      // fully up to date before running the action, and will re-run this
      // action if any input dependencies change. This is important because
      // this action may consume the outputs of previous steps.
      out_ << " |";
      path_output_.WriteFiles(out_, input_deps);
    }
    out_ << std::endl;

    // Response files require a unique name be defined.
    if (target_->action_values().uses_rsp_file())
      out_ << "  unique_name = " << i << std::endl;

    // The required types is the union of the args and response file. This
    // might theoretically duplicate a definition if the same substitution is
    // used in both the args and the response file. However, this should be
    // very unusual (normally the substitutions will go in one place or the
    // other) and the redundant assignment won't bother Ninja.
    SubstitutionWriter::WriteNinjaVariablesForSource(
        target_, settings_, sources[i],
        target_->action_values().args().required_types(), args_escape_options,
        out_);
    SubstitutionWriter::WriteNinjaVariablesForSource(
        target_, settings_, sources[i],
        target_->action_values().rsp_file_contents().required_types(),
        args_escape_options, out_);
    WriteNinjaVariablesForAction();

    if (target_->action_values().has_depfile()) {
      WriteDepfile(sources[i]);
    }
    if (target_->action_values().pool().ptr) {
      out_ << "  pool = ";
      out_ << target_->action_values().pool().ptr->GetNinjaName(
          settings_->default_toolchain_label());
      out_ << std::endl;
    }
  }
}

void NinjaActionTargetWriter::WriteOutputFilesForBuildLine(
    const SourceFile& source,
    std::vector<OutputFile>* output_files) {
  size_t first_output_index = output_files->size();

  SubstitutionWriter::ApplyListToSourceAsOutputFile(
      target_, settings_, target_->action_values().outputs(), source,
      output_files);

  for (size_t i = first_output_index; i < output_files->size(); i++) {
    out_ << " ";
    path_output_.WriteFile(out_, (*output_files)[i]);
  }
}

void NinjaActionTargetWriter::WriteDepfile(const SourceFile& source) {
  out_ << "  depfile = ";
  path_output_.WriteFile(
      out_,
      SubstitutionWriter::ApplyPatternToSourceAsOutputFile(
          target_, settings_, target_->action_values().depfile(), source));
  out_ << std::endl;
  // Using "deps = gcc" allows Ninja to read and store the depfile content in
  // its internal database which improves performance, especially for large
  // depfiles. The use of this feature with depfiles that contain multiple
  // outputs require Ninja version 1.9.0 or newer.
  if (settings_->build_settings()->ninja_required_version() >=
      Version{1, 9, 0}) {
    out_ << "  deps = gcc" << std::endl;
  }
}

void NinjaActionTargetWriter::WriteNinjaVariablesForAction() {
  SubstitutionBits subst;
  target_->action_values().args().FillRequiredTypes(&subst);
  WriteRustCompilerVars(subst, /*indent=*/true, /*always_write=*/false);
  WriteCCompilerVars(subst, /*indent=*/true, /*respect_source_types=*/false);
}
