// 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) : 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;
  }
}
