// 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;
  }
}
