// Copyright 2019 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_rust_binary_target_writer.h"

#include <sstream>

#include "base/strings/string_util.h"
#include "gn/deps_iterator.h"
#include "gn/filesystem_utils.h"
#include "gn/general_tool.h"
#include "gn/ninja_target_command_util.h"
#include "gn/ninja_utils.h"
#include "gn/rust_substitution_type.h"
#include "gn/substitution_writer.h"
#include "gn/target.h"

namespace {

// Returns the proper escape options for writing compiler and linker flags.
EscapeOptions GetFlagOptions() {
  EscapeOptions opts;
  opts.mode = ESCAPE_NINJA_COMMAND;
  return opts;
}

void WriteVar(const char* name,
              const std::string& value,
              EscapeOptions opts,
              std::ostream& out) {
  out << name << " = ";
  EscapeStringToStream(out, value, opts);
  out << std::endl;
}

void WriteCrateVars(const Target* target,
                    const Tool* tool,
                    EscapeOptions opts,
                    std::ostream& out) {
  WriteVar(kRustSubstitutionCrateName.ninja_name,
           target->rust_values().crate_name(), opts, out);

  std::string crate_type;
  switch (target->rust_values().crate_type()) {
    // Auto-select the crate type for executables, static libraries, and rlibs.
    case RustValues::CRATE_AUTO: {
      switch (target->output_type()) {
        case Target::EXECUTABLE:
          crate_type = "bin";
          break;
        case Target::STATIC_LIBRARY:
          crate_type = "staticlib";
          break;
        case Target::RUST_LIBRARY:
          crate_type = "rlib";
          break;
        case Target::RUST_PROC_MACRO:
          crate_type = "proc-macro";
          break;
        default:
          NOTREACHED();
      }
      break;
    }
    case RustValues::CRATE_BIN:
      crate_type = "bin";
      break;
    case RustValues::CRATE_CDYLIB:
      crate_type = "cdylib";
      break;
    case RustValues::CRATE_DYLIB:
      crate_type = "dylib";
      break;
    case RustValues::CRATE_PROC_MACRO:
      crate_type = "proc-macro";
      break;
    case RustValues::CRATE_RLIB:
      crate_type = "rlib";
      break;
    case RustValues::CRATE_STATICLIB:
      crate_type = "staticlib";
      break;
    default:
      NOTREACHED();
  }
  WriteVar(kRustSubstitutionCrateType.ninja_name, crate_type, opts, out);

  WriteVar(SubstitutionOutputExtension.ninja_name,
           SubstitutionWriter::GetLinkerSubstitution(
               target, tool, &SubstitutionOutputExtension),
           opts, out);
  WriteVar(SubstitutionOutputDir.ninja_name,
           SubstitutionWriter::GetLinkerSubstitution(target, tool,
                                                     &SubstitutionOutputDir),
           opts, out);
}

}  // namespace

NinjaRustBinaryTargetWriter::NinjaRustBinaryTargetWriter(const Target* target,
                                                         std::ostream& out)
    : NinjaBinaryTargetWriter(target, out),
      tool_(target->toolchain()->GetToolForTargetFinalOutputAsRust(target)) {}

NinjaRustBinaryTargetWriter::~NinjaRustBinaryTargetWriter() = default;

// TODO(juliehockett): add inherited library support? and IsLinkable support?
// for c-cross-compat
void NinjaRustBinaryTargetWriter::Run() {
  OutputFile input_dep = WriteInputsStampAndGetDep();

  // The input dependencies will be an order-only dependency. This will cause
  // Ninja to make sure the inputs are up to date before compiling this source,
  // but changes in the inputs deps won't cause the file to be recompiled. See
  // the comment on NinjaCBinaryTargetWriter::Run for more detailed explanation.
  size_t num_stamp_uses = target_->sources().size();
  std::vector<OutputFile> order_only_deps = WriteInputDepsStampAndGetDep(
      std::vector<const Target*>(), num_stamp_uses);

  // Public rust_library deps go in a --extern rlibs, public non-rust deps go in
  // -Ldependency rustdeps, and non-public source_sets get passed in as normal
  // source files
  UniqueVector<OutputFile> deps;
  AddSourceSetFiles(target_, &deps);
  if (target_->output_type() == Target::SOURCE_SET) {
    WriteSharedVars(target_->toolchain()->substitution_bits());
    WriteSourceSetStamp(deps.vector());
  } else {
    WriteCompilerVars();
    UniqueVector<const Target*> linkable_deps;
    UniqueVector<const Target*> non_linkable_deps;
    GetDeps(&deps, &linkable_deps, &non_linkable_deps);

    if (!input_dep.value().empty())
      order_only_deps.push_back(input_dep);

    std::vector<OutputFile> rustdeps;
    std::vector<OutputFile> nonrustdeps;
    for (const auto* non_linkable_dep : non_linkable_deps) {
      if (non_linkable_dep->source_types_used().RustSourceUsed() &&
          non_linkable_dep->output_type() != Target::SOURCE_SET) {
        rustdeps.push_back(non_linkable_dep->dependency_output_file());
      }
      order_only_deps.push_back(non_linkable_dep->dependency_output_file());
    }
    for (const auto* linkable_dep : linkable_deps) {
      if (linkable_dep->source_types_used().RustSourceUsed()) {
        rustdeps.push_back(linkable_dep->link_output_file());
      } else {
        nonrustdeps.push_back(linkable_dep->link_output_file());
      }
      deps.push_back(linkable_dep->dependency_output_file());
    }

    // Rust libraries specified by paths.
    for (ConfigValuesIterator iter(target_); !iter.done(); iter.Next()) {
      const ConfigValues& cur = iter.cur();
      for (const auto& e : cur.externs()) {
        if (e.second.is_source_file()) {
          deps.push_back(OutputFile(settings_->build_settings(),
                                    e.second.source_file()));
        }
      }
    }

    std::vector<OutputFile> tool_outputs;
    SubstitutionWriter::ApplyListToLinkerAsOutputFile(
        target_, tool_, tool_->outputs(), &tool_outputs);
    WriteCompilerBuildLine(target_->rust_values().crate_root(), deps.vector(),
                           order_only_deps, tool_->name(), tool_outputs);

    std::vector<const Target*> extern_deps(linkable_deps.vector());
    std::copy(non_linkable_deps.begin(), non_linkable_deps.end(),
              std::back_inserter(extern_deps));
    WriteExterns(extern_deps);
    WriteRustdeps(rustdeps, nonrustdeps);
  }
}

void NinjaRustBinaryTargetWriter::WriteCompilerVars() {
  const SubstitutionBits& subst = target_->toolchain()->substitution_bits();

  EscapeOptions opts = GetFlagOptions();
  WriteCrateVars(target_, tool_, opts, out_);

  WriteOneFlag(target_, &kRustSubstitutionRustFlags, false, Tool::kToolNone,
               &ConfigValues::rustflags, opts, path_output_, out_);

  WriteOneFlag(target_, &kRustSubstitutionRustEnv, false, Tool::kToolNone,
               &ConfigValues::rustenv, opts, path_output_, out_);

  WriteSharedVars(subst);
}

void NinjaRustBinaryTargetWriter::WriteExterns(
    const std::vector<const Target*>& deps) {
  out_ << "  externs =";

  for (const Target* target : deps) {
    if (target->output_type() == Target::RUST_LIBRARY ||
        target->output_type() == Target::RUST_PROC_MACRO) {
      out_ << " --extern ";
      const auto& renamed_dep =
          target_->rust_values().aliased_deps().find(target->label());
      if (renamed_dep != target_->rust_values().aliased_deps().end()) {
        out_ << renamed_dep->second << "=";
      } else {
        out_ << std::string(target->rust_values().crate_name()) << "=";
      }
      path_output_.WriteFile(out_, target->dependency_output_file());
    }
  }

  EscapeOptions extern_escape_opts;
  extern_escape_opts.mode = ESCAPE_NINJA_COMMAND;

  for (ConfigValuesIterator iter(target_); !iter.done(); iter.Next()) {
    const ConfigValues& cur = iter.cur();
    for (const auto& e : cur.externs()) {
      out_ << " --extern " << std::string(e.first) << "=";
      if (e.second.is_source_file()) {
        path_output_.WriteFile(out_, e.second.source_file());
      } else {
        EscapeStringToStream(out_, e.second.value(), extern_escape_opts);
      }
    }
  }

  out_ << std::endl;
}

void NinjaRustBinaryTargetWriter::WriteRustdeps(
    const std::vector<OutputFile>& rustdeps,
    const std::vector<OutputFile>& nonrustdeps) {
  out_ << "  rustdeps =";

  // Rust dependencies.
  for (const auto& rustdep : rustdeps) {
    out_ << " -Ldependency=";
    path_output_.WriteDir(
        out_, rustdep.AsSourceFile(settings_->build_settings()).GetDir(),
        PathOutput::DIR_NO_LAST_SLASH);
  }

  EscapeOptions lib_escape_opts;
  lib_escape_opts.mode = ESCAPE_NINJA_COMMAND;
  const std::string_view lib_prefix("lib");

  // Non-Rust native dependencies.
  for (const auto& nonrustdep : nonrustdeps) {
    out_ << " -Lnative=";
    path_output_.WriteDir(
        out_, nonrustdep.AsSourceFile(settings_->build_settings()).GetDir(),
        PathOutput::DIR_NO_LAST_SLASH);
    std::string_view file = FindFilenameNoExtension(&nonrustdep.value());
    if (!file.compare(0, lib_prefix.size(), lib_prefix)) {
      out_ << " -l";
      EscapeStringToStream(out_, file.substr(lib_prefix.size()),
                           lib_escape_opts);
    } else {
      out_ << " -Clink-arg=";
      path_output_.WriteFile(out_, nonrustdep);
    }
  }

  WriteLinkerFlags(out_, tool_, nullptr);
  WriteLibs(out_, tool_);
  out_ << std::endl;
}
