// Copyright 2014 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/tool.h"

#include "gn/c_tool.h"
#include "gn/general_tool.h"
#include "gn/rust_tool.h"
#include "gn/settings.h"
#include "gn/target.h"

const char* Tool::kToolNone = "";

Tool::Tool(const char* n) : name_(n) {}

Tool::~Tool() = default;

void Tool::SetToolComplete() {
  DCHECK(!complete_);
  complete_ = true;

  command_.FillRequiredTypes(&substitution_bits_);
  depfile_.FillRequiredTypes(&substitution_bits_);
  description_.FillRequiredTypes(&substitution_bits_);
  outputs_.FillRequiredTypes(&substitution_bits_);
  rspfile_.FillRequiredTypes(&substitution_bits_);
  rspfile_content_.FillRequiredTypes(&substitution_bits_);
  partial_outputs_.FillRequiredTypes(&substitution_bits_);
}

GeneralTool* Tool::AsGeneral() {
  return nullptr;
}

const GeneralTool* Tool::AsGeneral() const {
  return nullptr;
}

CTool* Tool::AsC() {
  return nullptr;
}

const CTool* Tool::AsC() const {
  return nullptr;
}

RustTool* Tool::AsRust() {
  return nullptr;
}
const RustTool* Tool::AsRust() const {
  return nullptr;
}

bool Tool::IsPatternInOutputList(const SubstitutionList& output_list,
                                 const SubstitutionPattern& pattern) const {
  for (const auto& cur : output_list.list()) {
    if (pattern.ranges().size() == cur.ranges().size() &&
        std::equal(pattern.ranges().begin(), pattern.ranges().end(),
                   cur.ranges().begin()))
      return true;
  }
  return false;
}

bool Tool::ValidateSubstitutionList(
    const std::vector<const Substitution*>& list,
    const Value* origin,
    Err* err) const {
  for (const auto& cur_type : list) {
    if (!ValidateSubstitution(cur_type)) {
      *err = Err(*origin, "Pattern not valid here.",
                 "You used the pattern " + std::string(cur_type->name) +
                     " which is not valid\nfor this variable.");
      return false;
    }
  }
  return true;
}

bool Tool::ReadBool(Scope* scope, const char* var, bool* field, Err* err) {
  DCHECK(!complete_);
  const Value* v = scope->GetValue(var, true);
  if (!v)
    return true;  // Not present is fine.
  if (!v->VerifyTypeIs(Value::BOOLEAN, err))
    return false;
  *field = v->boolean_value();
  return true;
}

bool Tool::ReadString(Scope* scope,
                      const char* var,
                      std::string* field,
                      Err* err) {
  DCHECK(!complete_);
  const Value* v = scope->GetValue(var, true);
  if (!v)
    return true;  // Not present is fine.
  if (!v->VerifyTypeIs(Value::STRING, err))
    return false;
  *field = v->string_value();
  return true;
}

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

  SubstitutionPattern pattern;
  if (!pattern.Parse(*value, err))
    return false;
  if (!ValidateSubstitutionList(pattern.required_types(), value, err))
    return false;

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

bool Tool::ReadPatternList(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 (!ValidateSubstitutionList(list.required_types(), value, err))
    return false;

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

bool Tool::ReadLabel(Scope* scope,
                     const char* var,
                     const Label& current_toolchain,
                     LabelPtrPair<Pool>* field,
                     Err* err) {
  DCHECK(!complete_);
  const Value* v = scope->GetValue(var, true);
  if (!v)
    return true;  // Not present is fine.

  Label label =
      Label::Resolve(scope->GetSourceDir(),
                     scope->settings()->build_settings()->root_path_utf8(),
                     current_toolchain, *v, err);
  if (err->has_error())
    return false;

  LabelPtrPair<Pool> pair(label);
  pair.origin = defined_from();

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

bool Tool::ReadOutputExtension(Scope* scope, Err* err) {
  DCHECK(!complete_);
  const Value* value = scope->GetValue("default_output_extension", true);
  if (!value)
    return true;  // Not present is fine.
  if (!value->VerifyTypeIs(Value::STRING, err))
    return false;

  if (value->string_value().empty())
    return true;  // Accept empty string.

  if (value->string_value()[0] != '.') {
    *err = Err(*value, "default_output_extension must begin with a '.'");
    return false;
  }

  set_default_output_extension(value->string_value());
  return true;
}

bool Tool::InitTool(Scope* scope, Toolchain* toolchain, Err* err) {
  if (!ReadPattern(scope, "command", &command_, err) ||
      !ReadString(scope, "command_launcher", &command_launcher_, err) ||
      !ReadOutputExtension(scope, err) ||
      !ReadPattern(scope, "depfile", &depfile_, err) ||
      !ReadPattern(scope, "description", &description_, err) ||
      !ReadPatternList(scope, "runtime_outputs", &runtime_outputs_, err) ||
      !ReadString(scope, "output_prefix", &output_prefix_, err) ||
      !ReadPattern(scope, "default_output_dir", &default_output_dir_, err) ||
      !ReadBool(scope, "restat", &restat_, err) ||
      !ReadPattern(scope, "rspfile", &rspfile_, err) ||
      !ReadPattern(scope, "rspfile_content", &rspfile_content_, err) ||
      !ReadLabel(scope, "pool", toolchain->label(), &pool_, err)) {
    return false;
  }
  const bool command_is_required = name_ != GeneralTool::kGeneralToolAction;
  if (command_.empty() == command_is_required) {
    *err = Err(defined_from(), "This tool's command is bad.",
               command_is_required
                   ? "This tool requires \"command\" to be defined."
                   : "This tool doesn't support \"command\".");
    return false;
  }
  return true;
}

std::unique_ptr<Tool> Tool::CreateTool(const ParseNode* function,
                                       const std::string& name,
                                       Scope* scope,
                                       Toolchain* toolchain,
                                       Err* err) {
  std::unique_ptr<Tool> tool = CreateTool(name);
  if (!tool) {
    *err = Err(function, "Unknown tool type.");
    return nullptr;
  }
  if (CTool* c_tool = tool->AsC()) {
    if (c_tool->InitTool(scope, toolchain, err))
      return tool;
    return nullptr;
  }
  if (GeneralTool* general_tool = tool->AsGeneral()) {
    if (general_tool->InitTool(scope, toolchain, err))
      return tool;
    return nullptr;
  }
  if (RustTool* rust_tool = tool->AsRust()) {
    if (rust_tool->InitTool(scope, toolchain, err))
      return tool;
    return nullptr;
  }
  NOTREACHED();
  *err = Err(function, "Unknown tool type.");
  return nullptr;
}

// static
std::unique_ptr<Tool> Tool::CreateTool(const std::string& name) {
  // C tools
  if (name == CTool::kCToolCc)
    return std::make_unique<CTool>(CTool::kCToolCc);
  else if (name == CTool::kCToolCxx)
    return std::make_unique<CTool>(CTool::kCToolCxx);
  else if (name == CTool::kCToolCxxModule)
    return std::make_unique<CTool>(CTool::kCToolCxxModule);
  else if (name == CTool::kCToolObjC)
    return std::make_unique<CTool>(CTool::kCToolObjC);
  else if (name == CTool::kCToolObjCxx)
    return std::make_unique<CTool>(CTool::kCToolObjCxx);
  else if (name == CTool::kCToolRc)
    return std::make_unique<CTool>(CTool::kCToolRc);
  else if (name == CTool::kCToolAsm)
    return std::make_unique<CTool>(CTool::kCToolAsm);
  else if (name == CTool::kCToolSwift)
    return std::make_unique<CTool>(CTool::kCToolSwift);
  else if (name == CTool::kCToolAlink)
    return std::make_unique<CTool>(CTool::kCToolAlink);
  else if (name == CTool::kCToolSolink)
    return std::make_unique<CTool>(CTool::kCToolSolink);
  else if (name == CTool::kCToolSolinkModule)
    return std::make_unique<CTool>(CTool::kCToolSolinkModule);
  else if (name == CTool::kCToolLink)
    return std::make_unique<CTool>(CTool::kCToolLink);

  // General tools
  else if (name == GeneralTool::kGeneralToolAction)
    return std::make_unique<GeneralTool>(GeneralTool::kGeneralToolAction);
  else if (name == GeneralTool::kGeneralToolStamp)
    return std::make_unique<GeneralTool>(GeneralTool::kGeneralToolStamp);
  else if (name == GeneralTool::kGeneralToolCopy)
    return std::make_unique<GeneralTool>(GeneralTool::kGeneralToolCopy);
  else if (name == GeneralTool::kGeneralToolCopyBundleData)
    return std::make_unique<GeneralTool>(
        GeneralTool::kGeneralToolCopyBundleData);
  else if (name == GeneralTool::kGeneralToolCompileXCAssets)
    return std::make_unique<GeneralTool>(
        GeneralTool::kGeneralToolCompileXCAssets);

  // Rust tool
  else if (name == RustTool::kRsToolBin)
    return std::make_unique<RustTool>(RustTool::kRsToolBin);
  else if (name == RustTool::kRsToolCDylib)
    return std::make_unique<RustTool>(RustTool::kRsToolCDylib);
  else if (name == RustTool::kRsToolDylib)
    return std::make_unique<RustTool>(RustTool::kRsToolDylib);
  else if (name == RustTool::kRsToolMacro)
    return std::make_unique<RustTool>(RustTool::kRsToolMacro);
  else if (name == RustTool::kRsToolRlib)
    return std::make_unique<RustTool>(RustTool::kRsToolRlib);
  else if (name == RustTool::kRsToolStaticlib)
    return std::make_unique<RustTool>(RustTool::kRsToolStaticlib);

  return nullptr;
}

// static
const char* Tool::GetToolTypeForSourceType(SourceFile::Type type) {
  switch (type) {
    case SourceFile::SOURCE_C:
      return CTool::kCToolCc;
    case SourceFile::SOURCE_CPP:
      return CTool::kCToolCxx;
    case SourceFile::SOURCE_MODULEMAP:
      return CTool::kCToolCxxModule;
    case SourceFile::SOURCE_M:
      return CTool::kCToolObjC;
    case SourceFile::SOURCE_MM:
      return CTool::kCToolObjCxx;
    case SourceFile::SOURCE_ASM:
    case SourceFile::SOURCE_S:
      return CTool::kCToolAsm;
    case SourceFile::SOURCE_RC:
      return CTool::kCToolRc;
    case SourceFile::SOURCE_RS:
      return RustTool::kRsToolBin;
    case SourceFile::SOURCE_SWIFT:
      return CTool::kCToolSwift;
    case SourceFile::SOURCE_UNKNOWN:
    case SourceFile::SOURCE_H:
    case SourceFile::SOURCE_O:
    case SourceFile::SOURCE_DEF:
    case SourceFile::SOURCE_GO:
      return kToolNone;
    default:
      NOTREACHED();
      return kToolNone;
  }
}

// static
const char* Tool::GetToolTypeForTargetFinalOutput(const Target* target) {
  // The contents of this list might be suprising (i.e. stamp tool for copy
  // rules). See the header for why.
  // TODO(crbug.com/gn/39): Don't emit stamp files for single-output targets.
  if (target->source_types_used().RustSourceUsed()) {
    switch (target->rust_values().crate_type()) {
      case RustValues::CRATE_AUTO: {
        switch (target->output_type()) {
          case Target::EXECUTABLE:
            return RustTool::kRsToolBin;
          case Target::SHARED_LIBRARY:
            return RustTool::kRsToolDylib;
          case Target::STATIC_LIBRARY:
            return RustTool::kRsToolStaticlib;
          case Target::RUST_LIBRARY:
            return RustTool::kRsToolRlib;
          case Target::RUST_PROC_MACRO:
            return RustTool::kRsToolMacro;
          default:
            break;
        }
        break;
      }
      case RustValues::CRATE_BIN:
        return RustTool::kRsToolBin;
      case RustValues::CRATE_CDYLIB:
        return RustTool::kRsToolCDylib;
      case RustValues::CRATE_DYLIB:
        return RustTool::kRsToolDylib;
      case RustValues::CRATE_PROC_MACRO:
        return RustTool::kRsToolMacro;
      case RustValues::CRATE_RLIB:
        return RustTool::kRsToolRlib;
      case RustValues::CRATE_STATICLIB:
        return RustTool::kRsToolStaticlib;
      default:
        NOTREACHED();
    }
  }
  switch (target->output_type()) {
    case Target::GROUP:
      return GeneralTool::kGeneralToolStamp;
    case Target::EXECUTABLE:
      return CTool::kCToolLink;
    case Target::SHARED_LIBRARY:
      return CTool::kCToolSolink;
    case Target::LOADABLE_MODULE:
      return CTool::kCToolSolinkModule;
    case Target::STATIC_LIBRARY:
      return CTool::kCToolAlink;
    case Target::SOURCE_SET:
      return GeneralTool::kGeneralToolStamp;
    case Target::ACTION:
    case Target::ACTION_FOREACH:
    case Target::BUNDLE_DATA:
    case Target::CREATE_BUNDLE:
    case Target::COPY_FILES:
    case Target::GENERATED_FILE:
      return GeneralTool::kGeneralToolStamp;
    default:
      NOTREACHED();
      return kToolNone;
  }
}
