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

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

const char* Tool::kToolNone = "";

Tool::Tool(const char* n)
    : defined_from_(nullptr), restat_(false), complete_(false), 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_);
}

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(), 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;
  }
  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::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::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::kRsToolRustc)
    return std::make_unique<RustTool>(RustTool::kRsToolRustc);

  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_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::kRsToolRustc;
    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())
    return RustTool::kRsToolRustc;
  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;
  }
}
