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

#include "base/strings/string_util.h"
#include "gn/general_tool.h"
#include "gn/ninja_utils.h"
#include "gn/output_file.h"
#include "gn/scheduler.h"
#include "gn/string_utils.h"
#include "gn/substitution_list.h"
#include "gn/substitution_writer.h"
#include "gn/target.h"
#include "gn/toolchain.h"

NinjaCopyTargetWriter::NinjaCopyTargetWriter(const Target* target,
                                             std::ostream& out)
    : NinjaTargetWriter(target, out) {}

NinjaCopyTargetWriter::~NinjaCopyTargetWriter() = default;

void NinjaCopyTargetWriter::Run() {
  const Tool* copy_tool =
      target_->toolchain()->GetTool(GeneralTool::kGeneralToolCopy);
  if (!copy_tool) {
    g_scheduler->FailWithError(Err(
        nullptr, "Copy tool not defined",
        "The toolchain " +
            target_->toolchain()->label().GetUserVisibleName(false) +
            "\n used by target " + target_->label().GetUserVisibleName(false) +
            "\n doesn't define a \"copy\" tool."));
    return;
  }

  SubstitutionBits required_bits = copy_tool->substitution_bits();
  if (!settings_->build_settings()->no_stamp_files()) {
    const Tool* stamp_tool =
        target_->toolchain()->GetTool(GeneralTool::kGeneralToolStamp);
    if (!stamp_tool) {
      g_scheduler->FailWithError(
          Err(nullptr, "Stamp tool not defined",
              "The toolchain " +
                  target_->toolchain()->label().GetUserVisibleName(false) +
                  "\n used by target " +
                  target_->label().GetUserVisibleName(false) +
                  "\n doesn't define a \"stamp\" tool."));
    }
    required_bits.MergeFrom(stamp_tool->substitution_bits());
  }

  // General target-related substitutions needed by the copy/stamp tool.
  WriteSharedVars(required_bits);

  std::vector<OutputFile> output_files;
  WriteCopyRules(&output_files);
  out_ << std::endl;
  WriteStampOrPhonyForTarget(output_files, std::vector<OutputFile>());
}

void NinjaCopyTargetWriter::WriteCopyRules(
    std::vector<OutputFile>* output_files) {
  CHECK(target_->action_values().outputs().list().size() == 1);
  const SubstitutionList& output_subst_list =
      target_->action_values().outputs();
  CHECK_EQ(1u, output_subst_list.list().size())
      << "Should have one entry exactly.";
  const SubstitutionPattern& output_subst = output_subst_list.list()[0];

  std::string tool_name =
      GetNinjaRulePrefixForToolchain(settings_) + GeneralTool::kGeneralToolCopy;

  size_t num_output_uses = target_->sources().size();
  NinjaTargetWriter::InputDeps stamp_deps = WriteInputDepsStampOrPhonyAndGetDep(
      std::vector<const Target*>(), num_output_uses);
  std::vector<OutputFile> implicit_deps = stamp_deps.implicit;
  std::vector<OutputFile> order_only_deps = stamp_deps.order_only;

  for (const Target* data_dep : resolved().GetDataDeps(target_)) {
    if (data_dep->has_dependency_output())
      order_only_deps.push_back(data_dep->dependency_output());
  }

  // Note that we don't write implicit deps for copy steps. "copy" only
  // depends on the output files themselves, rather than having includes
  // (the possibility of generated #includes is the main reason for implicit
  // dependencies).
  //
  // It would seem that specifying implicit dependencies on the deps of the
  // copy command would still be harmless. But Chrome implements copy tools
  // as hard links (much faster) which don't change the timestamp. If the
  // ninja rule looks like this:
  //   output: copy input | foo.stamp
  // The copy will not make a new timestamp on the output file, but the
  // foo.stamp file generated from a previous step will have a new timestamp.
  // The copy rule will therefore look out-of-date to Ninja and the rule will
  // get rebuilt.
  //
  // If this copy is copying a generated file, not listing the implicit
  // dependency will be fine as long as the input to the copy is properly
  // listed as the output from the step that generated it.
  //
  // Moreover, doing this assumes that the copy step is always a simple
  // locally run command, so there is no need for a toolchain dependency.
  //
  // Note that there is the need in some cases for order-only dependencies
  // where a command might need to make sure something else runs before it runs
  // to avoid conflicts. This is also needed for data_deps on a copy target.
  // Such cases should be avoided where possible, but sometimes that's not
  // possible.
  for (const auto& input_file : target_->sources()) {
    OutputFile output_file =
        SubstitutionWriter::ApplyPatternToSourceAsOutputFile(
            target_, target_->settings(), output_subst, input_file);
    output_files->push_back(output_file);

    out_ << "build ";
    WriteOutput(std::move(output_file));

    out_ << ": " << tool_name << " ";
    path_output_.WriteFile(out_, input_file);
    if (!implicit_deps.empty()) {
      out_ << " |";
      path_output_.WriteFiles(out_, implicit_deps);
    }
    if (!order_only_deps.empty()) {
      out_ << " ||";
      path_output_.WriteFiles(out_, order_only_deps);
    }
    WriteValidations();
    out_ << std::endl;
  }
}
