// 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/rust_values.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() {
  DCHECK(target_->output_type() != Target::SOURCE_SET);

  size_t num_output_uses = target_->sources().size();

  std::vector<OutputFile> input_deps =
      WriteInputsStampOrPhonyAndGetDep(num_output_uses);

  WriteCompilerVars();

  // Classify our dependencies.
  ClassifiedDeps classified_deps = GetClassifiedDeps();

  // 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.
  std::vector<OutputFile> order_only_deps = WriteInputDepsStampOrPhonyAndGetDep(
      std::vector<const Target*>(), num_output_uses);
  std::copy(input_deps.begin(), input_deps.end(),
            std::back_inserter(order_only_deps));

  // Build lists which will go into different bits of the rustc command line.
  // Public rust_library deps go in a --extern rlibs, public non-rust deps go in
  // -Ldependency. Also assemble a list of extra (i.e. implicit) deps
  // for ninja dependency tracking.
  UniqueVector<OutputFile> implicit_deps;
  AppendSourcesAndInputsToImplicitDeps(&implicit_deps);
  implicit_deps.Append(classified_deps.extra_object_files.begin(),
                       classified_deps.extra_object_files.end());

  std::vector<OutputFile> rustdeps;
  std::vector<OutputFile> nonrustdeps;
  std::vector<OutputFile> swiftmodules;
  nonrustdeps.insert(nonrustdeps.end(),
                     classified_deps.extra_object_files.begin(),
                     classified_deps.extra_object_files.end());
  for (const auto* framework_dep : classified_deps.framework_deps) {
    if (framework_dep->has_dependency_output_file()) {
      order_only_deps.push_back(framework_dep->dependency_output_file());
    }
  }
  if (target_->IsFinal()) {
    for (const Target* dep : classified_deps.swiftmodule_deps) {
      swiftmodules.push_back(dep->swift_values().module_output_file());
      order_only_deps.push_back(dep->swift_values().module_output_file());
    }
  }
  for (const auto* non_linkable_dep : classified_deps.non_linkable_deps) {
    if (non_linkable_dep->has_dependency_output()) {
      if (non_linkable_dep->source_types_used().RustSourceUsed() &&
          non_linkable_dep->output_type() != Target::SOURCE_SET) {
        rustdeps.push_back(non_linkable_dep->dependency_output());
      }
      order_only_deps.push_back(non_linkable_dep->dependency_output());
    }
  }
  for (const auto* linkable_dep : classified_deps.linkable_deps) {
    // Rust cdylibs are treated as non-Rust dependencies for linking purposes.
    if (linkable_dep->source_types_used().RustSourceUsed() &&
        linkable_dep->rust_values().crate_type() != RustValues::CRATE_CDYLIB) {
      rustdeps.push_back(linkable_dep->link_output_file());
    } else {
      nonrustdeps.push_back(linkable_dep->link_output_file());
    }
    CHECK(linkable_dep->has_dependency_output_file());
    implicit_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()) {
        implicit_deps.push_back(
            OutputFile(settings_->build_settings(), e.second.source_file()));
      }
    }
  }

  // Collect the full transitive set of rust libraries that this target depends
  // on, and the public flag represents if the target has direct access to the
  // dependency through a chain of public_deps.
  std::vector<ExternCrate> transitive_crates;
  for (const auto& inherited : resolved().GetRustInheritedLibraries(target_)) {
    const Target* dep = inherited.target();
    bool has_direct_access = inherited.is_public();
    // We will tell rustc to look for crate metadata for any rust crate
    // dependencies except cdylibs, as they have no metadata present.
    if (dep->source_types_used().RustSourceUsed() &&
        RustValues::IsRustLibrary(dep)) {
      transitive_crates.push_back({dep, has_direct_access});
      // If the current crate can directly acccess the `dep` crate, then the
      // current crate needs an implicit dependency on `dep` so it will be
      // rebuilt if `dep` changes.
      if (has_direct_access) {
        implicit_deps.push_back(dep->dependency_output_file());
      }
    }
  }

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

  std::vector<const Target*> extern_deps(
      classified_deps.linkable_deps.vector());
  std::copy(classified_deps.non_linkable_deps.begin(),
            classified_deps.non_linkable_deps.end(),
            std::back_inserter(extern_deps));

  WriteExternsAndDeps(extern_deps, transitive_crates, rustdeps, nonrustdeps,
                      swiftmodules);
  WriteSourcesAndInputs();
  WritePool(out_);
}

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

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

  WriteRustCompilerVars(subst, /*indent=*/false, /*always_write=*/true);

  WriteSharedVars(subst);
}

void NinjaRustBinaryTargetWriter::AppendSourcesAndInputsToImplicitDeps(
    UniqueVector<OutputFile>* deps) const {
  // Only the crate_root file needs to be given to rustc as input.
  // Any other 'sources' are just implicit deps.
  // Most Rust targets won't bother specifying the "sources =" line
  // because it is handled sufficiently by crate_root and the generation
  // of depfiles by rustc. But for those which do...
  for (const auto& source : target_->sources()) {
    deps->push_back(OutputFile(settings_->build_settings(), source));
  }
  for (const auto& data : target_->config_values().inputs()) {
    deps->push_back(OutputFile(settings_->build_settings(), data));
  }
}

void NinjaRustBinaryTargetWriter::WriteSourcesAndInputs() {
  out_ << "  sources =";
  for (const auto& source : target_->sources()) {
    out_ << " ";
    path_output_.WriteFile(out_,
                           OutputFile(settings_->build_settings(), source));
  }
  for (const auto& data : target_->config_values().inputs()) {
    out_ << " ";
    path_output_.WriteFile(out_, OutputFile(settings_->build_settings(), data));
  }
  out_ << std::endl;
}

void NinjaRustBinaryTargetWriter::WriteExternsAndDeps(
    const std::vector<const Target*>& deps,
    const std::vector<ExternCrate>& transitive_rust_deps,
    const std::vector<OutputFile>& rustdeps,
    const std::vector<OutputFile>& nonrustdeps,
    const std::vector<OutputFile>& swiftmodules) {
  // Writes a external LibFile which comes from user-specified externs, and may
  // be either a string or a SourceFile.
  auto write_extern_lib_file = [this](std::string_view crate_name,
                                      LibFile lib_file) {
    out_ << " --extern ";
    out_ << crate_name;
    out_ << "=";
    if (lib_file.is_source_file()) {
      path_output_.WriteFile(out_, lib_file.source_file());
    } else {
      EscapeOptions escape_opts_command;
      escape_opts_command.mode = ESCAPE_NINJA_COMMAND;
      EscapeStringToStream(out_, lib_file.value(), escape_opts_command);
    }
  };
  // Writes an external OutputFile which comes from a dependency of the current
  // target.
  auto write_extern_target = [this](const Target& dep) {
    std::string_view crate_name;
    const auto& aliased_deps = target_->rust_values().aliased_deps();
    if (auto it = aliased_deps.find(dep.label()); it != aliased_deps.end()) {
      crate_name = it->second;
    } else {
      crate_name = dep.rust_values().crate_name();
    }

    out_ << " --extern ";
    out_ << crate_name;
    out_ << "=";
    path_output_.WriteFile(out_, dep.dependency_output_file());
  };

  // Write accessible crates with `--extern` to add them to the extern prelude.
  out_ << "  externs =";

  // Tracking to avoid emitted the same lib twice. We track it instead of
  // pre-emptively constructing a UniqueVector since we would have to also store
  // the crate name, and in the future the public-ness.
  std::unordered_set<OutputFile> emitted_rust_libs;
  // TODO: We defer private dependencies to -Ldependency until --extern priv is
  // stabilized.
  UniqueVector<SourceDir> private_extern_dirs;

  // Walk the transitive closure of all rust dependencies.
  //
  // For dependencies that are meant to be accessible we pass them to --extern
  // in order to add them to the crate's extern prelude.
  //
  // For all transitive dependencies, we add them to `private_extern_dirs` in
  // order to generate a -Ldependency switch that points to them. This ensures
  // that rustc can find them if they are used by other dependencies. For
  // example:
  //
  //   A -> C --public--> D
  //     -> B --private-> D
  //
  // Here A has direct access to D, but B and C also make use of D, and they
  // will only search the paths specified to -Ldependency, thus D needs to
  // appear as both a --extern (for A) and -Ldependency (for B and C).
  for (const auto& crate : transitive_rust_deps) {
    const OutputFile& rust_lib = crate.target->dependency_output_file();
    if (emitted_rust_libs.count(rust_lib) == 0) {
      if (crate.has_direct_access) {
        write_extern_target(*crate.target);
      }
      emitted_rust_libs.insert(rust_lib);
    }
    private_extern_dirs.push_back(
        rust_lib.AsSourceFile(settings_->build_settings()).GetDir());
  }

  // Add explicitly specified externs from the GN target.
  for (ConfigValuesIterator iter(target_); !iter.done(); iter.Next()) {
    const ConfigValues& cur = iter.cur();
    for (const auto& [crate_name, lib_file] : cur.externs()) {
      write_extern_lib_file(crate_name, lib_file);
    }
  }

  out_ << std::endl;
  out_ << "  rustdeps =";

  for (const SourceDir& dir : private_extern_dirs) {
    // TODO: switch to using `--extern priv:name` after stabilization.
    out_ << " -Ldependency=";
    path_output_.WriteDir(out_, dir, PathOutput::DIR_NO_LAST_SLASH);
  }

  // If rustc will invoke a linker, then pass linker arguments to include those
  // non-Rust native dependencies in the linking step.

  // Before outputting any libraries to link, ensure the linker is in a mode
  // that allows dynamic linking, as rustc may have previously put it into
  // static-only mode.
  if (nonrustdeps.size() > 0) {
    out_ << " " << tool_->dynamic_link_switch();
  }
  for (const auto& nonrustdep : nonrustdeps) {
    out_ << " -Clink-arg=";
    path_output_.WriteFile(out_, nonrustdep);
  }

  // Library search paths are required to find system libraries named in #[link]
  // directives, which will not be specified in non-Rust native dependencies.
  WriteLibrarySearchPath(out_, tool_);
  // If rustc will invoke a linker, all libraries need the passed through to the
  // linker.
  WriteLibs(out_, tool_);
  WriteFrameworks(out_, tool_);
  WriteSwiftModules(out_, tool_, swiftmodules);

  out_ << std::endl;
  out_ << "  ldflags =";
  // If rustc will invoke a linker, linker flags need to be forwarded through to
  // the linker.
  WriteCustomLinkerFlags(out_, tool_);

  out_ << std::endl;
}
