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

#include "tools/gn/rust_substitution_type.h"
#include "tools/gn/target.h"

const char* RustTool::kRsToolRustc = "rustc";

RustTool::RustTool(const char* n) : Tool(n), rlib_output_extension_(".rlib") {
  CHECK(ValidateName(n));
}

RustTool::~RustTool() = default;

RustTool* RustTool::AsRust() {
  return this;
}
const RustTool* RustTool::AsRust() const {
  return this;
}

bool RustTool::ValidateName(const char* name) const {
  return name_ == kRsToolRustc;
}

void RustTool::SetComplete() {
  SetToolComplete();
}

bool RustTool::SetOutputExtension(const Value* value,
                                  std::string* var,
                                  Err* err) {
  DCHECK(!complete_);
  if (!value)
    return true;  // Not present is fine.
  if (!value->VerifyTypeIs(Value::STRING, err))
    return false;
  if (value->string_value().empty())
    return true;

  *var = std::move(value->string_value());
  return true;
}

bool RustTool::ReadOutputExtensions(Scope* scope, Err* err) {
  if (!SetOutputExtension(scope->GetValue("exe_output_extension", true),
                          &exe_output_extension_, err))
    return false;
  if (!SetOutputExtension(scope->GetValue("rlib_output_extension", true),
                          &rlib_output_extension_, err))
    return false;
  if (!SetOutputExtension(scope->GetValue("dylib_output_extension", true),
                          &dylib_output_extension_, err))
    return false;
  if (!SetOutputExtension(scope->GetValue("cdylib_output_extension", true),
                          &cdylib_output_extension_, err))
    return false;
  if (!SetOutputExtension(scope->GetValue("staticlib_output_extension", true),
                          &staticlib_output_extension_, err))
    return false;
  if (!SetOutputExtension(scope->GetValue("proc_macro_output_extension", true),
                          &proc_macro_output_extension_, err))
    return false;
  return true;
}

bool RustTool::ReadOutputsPatternList(Scope* scope,
                                      const char* var,
                                      SubstitutionList* field,
                                      Err* err) {
  DCHECK(!complete_);
  const Value* value = scope->GetValue(var, true);
  if (!value)
    return true;  // Not present is fine.
  if (!value->VerifyTypeIs(Value::LIST, err))
    return false;

  SubstitutionList list;
  if (!list.Parse(*value, err))
    return false;

  // Validate the right kinds of patterns are used.
  if (list.list().empty()) {
    *err = Err(defined_from(), "\"outputs\" must be specified for this tool.");
    return false;
  }

  for (const auto& cur_type : list.required_types()) {
    if (!IsValidRustSubstitution(cur_type)) {
      *err = Err(*value, "Pattern not valid here.",
                 "You used the pattern " + std::string(cur_type->name) +
                     " which is not valid\nfor this variable.");
      return false;
    }
  }

  *field = std::move(list);
  return true;
}

bool RustTool::InitTool(Scope* scope, Toolchain* toolchain, Err* err) {
  // Initialize default vars.
  if (!Tool::InitTool(scope, toolchain, err)) {
    return false;
  }

  if (!ReadOutputExtensions(scope, err)) {
    return false;
  }

  // All Rust tools should have outputs.
  if (!ReadOutputsPatternList(scope, "outputs", &outputs_, err)) {
    return false;
  }

  return true;
}

bool RustTool::ValidateSubstitution(const Substitution* sub_type) const {
  if (name_ == kRsToolRustc)
    return IsValidRustSubstitution(sub_type);
  NOTREACHED();
  return false;
}

const std::string& RustTool::rustc_output_extension(
    Target::OutputType type,
    const RustValues::CrateType crate_type) const {
  switch (crate_type) {
    case RustValues::CRATE_AUTO: {
      switch (type) {
        case Target::EXECUTABLE:
          return exe_output_extension_;
        case Target::STATIC_LIBRARY:
          return staticlib_output_extension_;
        case Target::RUST_LIBRARY:
          return rlib_output_extension_;
        default:
          NOTREACHED();
          return exe_output_extension_;
      }
    }
    case RustValues::CRATE_DYLIB:
      return dylib_output_extension_;
    case RustValues::CRATE_CDYLIB:
      return cdylib_output_extension_;
    case RustValues::CRATE_PROC_MACRO:
      return proc_macro_output_extension_;
    default:
      NOTREACHED();
      return exe_output_extension_;
  }
}
