// 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 (!FillEdition())
    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::FillEdition() {
  const Value* value = scope_->GetValue(variables::kRustEdition, true);
  if (!value) {
    *err_ = Err(function_call_, "Missing \"edition\" in Rust target.");
    return false;
  }

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

  target_->rust_values().edition() = std::move(value->string_value());
  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;
}
