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

#include <sstream>

#include "tools/gn/deps_iterator.h"
#include "tools/gn/general_tool.h"
#include "tools/gn/ninja_target_command_util.h"
#include "tools/gn/ninja_utils.h"
#include "tools/gn/rust_substitution_type.h"
#include "tools/gn/substitution_writer.h"
#include "tools/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->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::SHARED_LIBRARY:
      switch (target->rust_values().crate_type()) {
        case RustValues::CRATE_DYLIB:
          crate_type = "dylib";
          break;
        case RustValues::CRATE_CDYLIB:
          crate_type = "cdylib";
          break;
        case RustValues::CRATE_PROC_MACRO:
          crate_type = "proc-macro";
          break;
        default:
          NOTREACHED();
      }
    default:
      NOTREACHED();
  }
  WriteVar(kRustSubstitutionCrateType.ninja_name, crate_type, opts, out);

  if (!target->output_extension_set()) {
    DCHECK(tool->AsRust());
    WriteVar(kRustSubstitutionOutputExtension.ninja_name,
             tool->AsRust()->rustc_output_extension(
                 target->output_type(), target->rust_values().crate_type()),
             opts, out);
  } else if (target->output_extension().empty()) {
    WriteVar(kRustSubstitutionOutputExtension.ninja_name, "", opts, out);
  } else {
    WriteVar(kRustSubstitutionOutputExtension.ninja_name,
             std::string(".") + target->output_extension(), opts, out);
  }

  if (target->output_type() == Target::RUST_LIBRARY ||
      target->output_type() == Target::SHARED_LIBRARY)
    WriteVar(kRustSubstitutionOutputPrefix.ninja_name, "lib", 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;
    for (const auto* non_linkable_dep : non_linkable_deps) {
      order_only_deps.push_back(non_linkable_dep->dependency_output_file());
    }

    for (const auto* linkable_dep : linkable_deps) {
      rustdeps.push_back(linkable_dep->dependency_output_file());
      deps.push_back(linkable_dep->dependency_output_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);
    WriteExterns();
    WriteRustdeps(rustdeps);
    WriteEdition();
  }
}

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

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

  WriteOneFlag(target_, &kRustSubstitutionRustFlags, false,
               RustTool::kRsToolRustc, &ConfigValues::rustflags, opts,
               path_output_, out_);

  WriteOneFlag(target_, &kRustSubstitutionRustEnv, false,
               RustTool::kRsToolRustc, &ConfigValues::rustenv, opts,
               path_output_, out_);

  WriteSharedVars(subst);
}

void NinjaRustBinaryTargetWriter::WriteExterns() {
  std::vector<const Target*> externs;
  for (const auto& pair : target_->GetDeps(Target::DEPS_LINKED)) {
    if (pair.ptr->output_type() == Target::RUST_LIBRARY) {
      externs.push_back(pair.ptr);
    }
  }
  if (externs.empty())
    return;
  out_ << "  externs =";
  for (const Target* ex : externs) {
    out_ << " --extern ";

    const auto& renamed_dep =
        target_->rust_values().aliased_deps().find(ex->label());
    if (renamed_dep != target_->rust_values().aliased_deps().end()) {
      out_ << renamed_dep->second << "=";
    } else {
      out_ << std::string(ex->rust_values().crate_name()) << "=";
    }

    path_output_.WriteFile(out_, ex->dependency_output_file());
  }
  out_ << std::endl;
}

void NinjaRustBinaryTargetWriter::WriteRustdeps(
    std::vector<OutputFile>& rustdeps) {
  if (rustdeps.empty())
    return;
  out_ << "  rustdeps =";
  for (const auto& rustdep : rustdeps) {
    out_ << " -Ldependency=";
    path_output_.WriteDir(
        out_, rustdep.AsSourceFile(settings_->build_settings()).GetDir(),
        PathOutput::DIR_NO_LAST_SLASH);
  }
  out_ << std::endl;
}

void NinjaRustBinaryTargetWriter::WriteEdition() {
  DCHECK(!target_->rust_values().edition().empty());
  out_ << "  edition = " << target_->rust_values().edition() << std::endl;
}