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

#include "base/strings/string_util.h"
#include "tools/gn/ninja_utils.h"
#include "tools/gn/output_file.h"
#include "tools/gn/scheduler.h"
#include "tools/gn/string_utils.h"
#include "tools/gn/substitution_list.h"
#include "tools/gn/substitution_writer.h"
#include "tools/gn/target.h"
#include "tools/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(Toolchain::TYPE_COPY);
  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;
  }

  const Tool* stamp_tool = target_->toolchain()->GetTool(Toolchain::TYPE_STAMP);
  if (!stamp_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 \"stamp\" tool."));
    return;
  }

  // Figure out the substitutions used by the copy and stamp tools.
  SubstitutionBits required_bits = copy_tool->substitution_bits();
  required_bits.MergeFrom(stamp_tool->substitution_bits());

  // General target-related substitutions needed by both tools.
  WriteSharedVars(required_bits);

  std::vector<OutputFile> output_files;
  WriteCopyRules(&output_files);
  out_ << std::endl;
  WriteStampForTarget(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_) +
      Toolchain::ToolTypeToName(Toolchain::TYPE_COPY);

  size_t num_stamp_uses = target_->sources().size();
  std::vector<OutputFile> input_deps = WriteInputDepsStampAndGetDep(
      std::vector<const Target*>(), num_stamp_uses);

  // 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 harmeless. 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. 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 ";
    path_output_.WriteFile(out_, output_file);
    out_ << ": " << tool_name << " ";
    path_output_.WriteFile(out_, input_file);
    if (!input_deps.empty()) {
      out_ << " ||";
      path_output_.WriteFiles(out_, input_deps);
    }
    out_ << std::endl;
  }
}
