// 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/rust_values_generator.h"

#include "tools/gn/config_values_generator.h"
#include "tools/gn/err.h"
#include "tools/gn/filesystem_utils.h"
#include "tools/gn/functions.h"
#include "tools/gn/parse_tree.h"
#include "tools/gn/rust_variables.h"
#include "tools/gn/scope.h"
#include "tools/gn/target.h"
#include "tools/gn/value_extractors.h"

static const char* kRustSupportedCrateTypesError =
    "\"crate_type\" must be one of \"bin\", \"cdylib\", \"dylib\", or "
    "\"proc-macro\", \"rlib\", \"staticlib\".";

RustTargetGenerator::RustTargetGenerator(Target* target,
                                         Scope* scope,
                                         const FunctionCallNode* function_call,
                                         Err* err)
    : target_(target),
      scope_(scope),
      function_call_(function_call),
      err_(err) {}

RustTargetGenerator::~RustTargetGenerator() = default;

void RustTargetGenerator::Run() {
  // source_set targets don't need any special Rust handling.
  if (target_->output_type() == Target::SOURCE_SET)
    return;

  // Check that this type of target is Rust-supported.
  if (target_->output_type() != Target::EXECUTABLE &&
      target_->output_type() != Target::SHARED_LIBRARY &&
      target_->output_type() != Target::RUST_LIBRARY &&
      target_->output_type() != Target::STATIC_LIBRARY &&
      target_->output_type() != Target::LOADABLE_MODULE) {
    // Only valid rust output types.
    *err_ = Err(function_call_,
                "Target type \"" +
                    std::string(Target::GetStringForOutputType(
                        target_->output_type())) +
                    "\" is not supported for Rust compilation.",
                "Supported target types are \"executable\", \"loadable_module\""
                "\"shared_library\", \"static_library\", or \"source_set\".");
    return;
  }

  if (!FillCrateName())
    return;

  if (!FillCrateType())
    return;

  if (!FillCrateRoot())
    return;

  if (!FillAliasedDeps())
    return;
}

bool RustTargetGenerator::FillCrateName() {
  const Value* value = scope_->GetValue(variables::kRustCrateName, true);
  if (!value) {
    // The target name will be used.
    target_->rust_values().crate_name() = target_->label().name();
    return true;
  }
  if (!value->VerifyTypeIs(Value::STRING, err_))
    return false;

  target_->rust_values().crate_name() = std::move(value->string_value());
  return true;
}

bool RustTargetGenerator::FillCrateType() {
  const Value* value = scope_->GetValue(variables::kRustCrateType, true);
  if (!value) {
    // Require shared_library and loadable_module targets to tell us what
    // they want.
    if (target_->output_type() == Target::SHARED_LIBRARY ||
        target_->output_type() == Target::LOADABLE_MODULE) {
      *err_ = Err(function_call_,
                  "Must set \"crate_type\" on a Rust \"shared_library\".",
                  kRustSupportedCrateTypesError);
      return false;
    }

    return true;
  }

  if (!value->VerifyTypeIs(Value::STRING, err_))
    return false;

  if (value->string_value() == "bin") {
    target_->rust_values().set_crate_type(RustValues::CRATE_BIN);
    return true;
  }
  if (value->string_value() == "cdylib") {
    target_->rust_values().set_crate_type(RustValues::CRATE_CDYLIB);
    return true;
  }
  if (value->string_value() == "dylib") {
    target_->rust_values().set_crate_type(RustValues::CRATE_DYLIB);
    return true;
  }
  if (value->string_value() == "proc-macro") {
    target_->rust_values().set_crate_type(RustValues::CRATE_PROC_MACRO);
    return true;
  }
  if (value->string_value() == "rlib") {
    target_->rust_values().set_crate_type(RustValues::CRATE_RLIB);
    return true;
  }
  if (value->string_value() == "staticlib") {
    target_->rust_values().set_crate_type(RustValues::CRATE_STATICLIB);
    return true;
  }

  *err_ = Err(value->origin(),
              "Inadmissible crate type \"" + value->string_value() + "\".",
              kRustSupportedCrateTypesError);
  return false;
}

bool RustTargetGenerator::FillCrateRoot() {
  const Value* value = scope_->GetValue(variables::kRustCrateRoot, true);
  if (!value) {
    // If there's only one source, use that.
    if (target_->sources().size() == 1) {
      target_->rust_values().set_crate_root(target_->sources()[0]);
      return true;
    }
    // Otherwise, see if "lib.rs" or "main.rs" (as relevant) are in sources.
    std::string to_find =
        target_->output_type() == Target::EXECUTABLE ? "main.rs" : "lib.rs";
    for (auto& source : target_->sources()) {
      if (source.GetName() == to_find) {
        target_->rust_values().set_crate_root(source);
        return true;
      }
    }
    *err_ = Err(function_call_, "Missing \"crate_root\" and missing \"" +
                                    to_find + "\" in sources.");
    return false;
  }

  if (!value->VerifyTypeIs(Value::STRING, err_))
    return false;

  SourceFile dest;
  if (!ExtractRelativeFile(scope_->settings()->build_settings(), *value,
                           scope_->GetSourceDir(), &dest, err_))
    return false;

  target_->rust_values().set_crate_root(dest);
  return true;
}

bool RustTargetGenerator::FillAliasedDeps() {
  const Value* value = scope_->GetValue(variables::kRustAliasedDeps, true);
  if (!value)
    return true;

  if (!value->VerifyTypeIs(Value::SCOPE, err_))
    return false;

  Scope::KeyValueMap aliased_deps;
  value->scope_value()->GetCurrentScopeValues(&aliased_deps);
  for (const auto& pair : aliased_deps) {
    Label dep_label =
        Label::Resolve(scope_->GetSourceDir(), ToolchainLabelForScope(scope_),
                       pair.second, err_);

    if (err_->has_error())
      return false;

    // Insert into the aliased_deps map.
    target_->rust_values().aliased_deps().emplace(std::move(dep_label),
                                                  pair.first);
  }

  return true;
}
