// Copyright 2017 the V8 project 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 "src/torque/declarations.h"
#include "src/torque/declarable.h"
#include "src/torque/global-context.h"
#include "src/torque/server-data.h"
#include "src/torque/type-oracle.h"

namespace v8 {
namespace internal {
namespace torque {
namespace {

template <class T>
std::vector<T> EnsureNonempty(std::vector<T> list, const std::string& name,
                              const char* kind) {
  if (list.empty()) {
    ReportError("there is no ", kind, " named ", name);
  }
  return std::move(list);
}

template <class T, class Name>
T EnsureUnique(const std::vector<T>& list, const Name& name, const char* kind) {
  if (list.empty()) {
    ReportError("there is no ", kind, " named ", name);
  }
  if (list.size() >= 2) {
    ReportError("ambiguous reference to ", kind, " ", name);
  }
  return list.front();
}

template <class T>
void CheckAlreadyDeclared(const std::string& name, const char* new_type) {
  std::vector<T*> declarations =
      FilterDeclarables<T>(Declarations::TryLookupShallow(QualifiedName(name)));
  if (!declarations.empty()) {
    Scope* scope = CurrentScope::Get();
    ReportError("cannot redeclare ", name, " (type ", *new_type, scope, ")");
  }
}

}  // namespace

std::vector<Declarable*> Declarations::LookupGlobalScope(
    const QualifiedName& name) {
  std::vector<Declarable*> d =
      GlobalContext::GetDefaultNamespace()->Lookup(name);
  if (d.empty()) {
    std::stringstream s;
    s << "cannot find \"" << name << "\" in global scope";
    ReportError(s.str());
  }
  return d;
}

const TypeAlias* Declarations::LookupTypeAlias(const QualifiedName& name) {
  TypeAlias* declaration =
      EnsureUnique(FilterDeclarables<TypeAlias>(Lookup(name)), name, "type");
  return declaration;
}

const Type* Declarations::LookupType(const QualifiedName& name) {
  return LookupTypeAlias(name)->type();
}

const Type* Declarations::LookupType(const Identifier* name) {
  const TypeAlias* alias = LookupTypeAlias(QualifiedName(name->value));
  if (GlobalContext::collect_language_server_data()) {
    LanguageServerData::AddDefinition(name->pos,
                                      alias->GetDeclarationPosition());
  }
  return alias->type();
}

base::Optional<const Type*> Declarations::TryLookupType(
    const QualifiedName& name) {
  auto decls = FilterDeclarables<TypeAlias>(TryLookup(name));
  if (decls.empty()) return base::nullopt;
  return EnsureUnique(std::move(decls), name, "type")->type();
}

const Type* Declarations::LookupGlobalType(const QualifiedName& name) {
  TypeAlias* declaration = EnsureUnique(
      FilterDeclarables<TypeAlias>(LookupGlobalScope(name)), name, "type");
  return declaration->type();
}

Builtin* Declarations::FindSomeInternalBuiltinWithType(
    const BuiltinPointerType* type) {
  for (auto& declarable : GlobalContext::AllDeclarables()) {
    if (Builtin* builtin = Builtin::DynamicCast(declarable.get())) {
      if (!builtin->IsExternal() && builtin->kind() == Builtin::kStub &&
          builtin->signature().return_type == type->return_type() &&
          builtin->signature().parameter_types.types ==
              type->parameter_types()) {
        return builtin;
      }
    }
  }
  return nullptr;
}

Value* Declarations::LookupValue(const QualifiedName& name) {
  return EnsureUnique(FilterDeclarables<Value>(Lookup(name)), name, "value");
}

Macro* Declarations::TryLookupMacro(const std::string& name,
                                    const TypeVector& types) {
  std::vector<Macro*> macros = TryLookup<Macro>(QualifiedName(name));
  for (auto& m : macros) {
    auto signature_types = m->signature().GetExplicitTypes();
    if (signature_types == types && !m->signature().parameter_types.var_args) {
      return m;
    }
  }
  return nullptr;
}

base::Optional<Builtin*> Declarations::TryLookupBuiltin(
    const QualifiedName& name) {
  std::vector<Builtin*> builtins = TryLookup<Builtin>(name);
  if (builtins.empty()) return base::nullopt;
  return EnsureUnique(builtins, name.name, "builtin");
}

std::vector<GenericCallable*> Declarations::LookupGeneric(
    const std::string& name) {
  return EnsureNonempty(
      FilterDeclarables<GenericCallable>(Lookup(QualifiedName(name))), name,
      "generic callable");
}

GenericCallable* Declarations::LookupUniqueGeneric(const QualifiedName& name) {
  return EnsureUnique(FilterDeclarables<GenericCallable>(Lookup(name)), name,
                      "generic callable");
}

GenericType* Declarations::LookupUniqueGenericType(const QualifiedName& name) {
  return EnsureUnique(FilterDeclarables<GenericType>(Lookup(name)), name,
                      "generic type");
}

GenericType* Declarations::LookupGlobalUniqueGenericType(
    const std::string& name) {
  return EnsureUnique(
      FilterDeclarables<GenericType>(LookupGlobalScope(QualifiedName(name))),
      name, "generic type");
}

base::Optional<GenericType*> Declarations::TryLookupGenericType(
    const QualifiedName& name) {
  std::vector<GenericType*> results = TryLookup<GenericType>(name);
  if (results.empty()) return base::nullopt;
  return EnsureUnique(results, name.name, "generic type");
}

Namespace* Declarations::DeclareNamespace(const std::string& name) {
  return Declare(name, std::make_unique<Namespace>(name));
}

TypeAlias* Declarations::DeclareType(const Identifier* name, const Type* type) {
  CheckAlreadyDeclared<TypeAlias>(name->value, "type");
  return Declare(name->value, std::unique_ptr<TypeAlias>(
                                  new TypeAlias(type, true, name->pos)));
}

const TypeAlias* Declarations::PredeclareTypeAlias(const Identifier* name,
                                                   TypeDeclaration* type,
                                                   bool redeclaration) {
  CheckAlreadyDeclared<TypeAlias>(name->value, "type");
  std::unique_ptr<TypeAlias> alias_ptr(
      new TypeAlias(type, redeclaration, name->pos));
  return Declare(name->value, std::move(alias_ptr));
}

TorqueMacro* Declarations::CreateTorqueMacro(std::string external_name,
                                             std::string readable_name,
                                             bool exported_to_csa,
                                             Signature signature,
                                             base::Optional<Statement*> body,
                                             bool is_user_defined) {
  external_name = GlobalContext::MakeUniqueName(external_name);
  return RegisterDeclarable(std::unique_ptr<TorqueMacro>(new TorqueMacro(
      std::move(external_name), std::move(readable_name), std::move(signature),
      body, is_user_defined, exported_to_csa)));
}

ExternMacro* Declarations::CreateExternMacro(
    std::string name, std::string external_assembler_name,
    Signature signature) {
  return RegisterDeclarable(std::unique_ptr<ExternMacro>(
      new ExternMacro(std::move(name), std::move(external_assembler_name),
                      std::move(signature))));
}

Macro* Declarations::DeclareMacro(
    const std::string& name, bool accessible_from_csa,
    base::Optional<std::string> external_assembler_name,
    const Signature& signature, base::Optional<Statement*> body,
    base::Optional<std::string> op, bool is_user_defined) {
  if (TryLookupMacro(name, signature.GetExplicitTypes())) {
    ReportError("cannot redeclare macro ", name,
                " with identical explicit parameters");
  }
  Macro* macro;
  if (external_assembler_name) {
    macro =
        CreateExternMacro(name, std::move(*external_assembler_name), signature);
  } else {
    macro = CreateTorqueMacro(name, name, accessible_from_csa, signature, body,
                              is_user_defined);
  }

  Declare(name, macro);
  if (op) {
    if (TryLookupMacro(*op, signature.GetExplicitTypes())) {
      ReportError("cannot redeclare operator ", name,
                  " with identical explicit parameters");
    }
    DeclareOperator(*op, macro);
  }
  return macro;
}

Method* Declarations::CreateMethod(AggregateType* container_type,
                                   const std::string& name, Signature signature,
                                   Statement* body) {
  std::string generated_name = GlobalContext::MakeUniqueName(
      "Method_" + container_type->SimpleName() + "_" + name);
  Method* result = RegisterDeclarable(std::unique_ptr<Method>(new Method(
      container_type, generated_name, name, std::move(signature), body)));
  container_type->RegisterMethod(result);
  return result;
}

Intrinsic* Declarations::CreateIntrinsic(const std::string& name,
                                         const Signature& signature) {
  Intrinsic* result = RegisterDeclarable(std::unique_ptr<Intrinsic>(
      new Intrinsic(std::move(name), std::move(signature))));
  return result;
}

Intrinsic* Declarations::DeclareIntrinsic(const std::string& name,
                                          const Signature& signature) {
  Intrinsic* result = CreateIntrinsic(std::move(name), std::move(signature));
  Declare(name, result);
  return result;
}

Builtin* Declarations::CreateBuiltin(std::string external_name,
                                     std::string readable_name,
                                     Builtin::Kind kind, Signature signature,

                                     base::Optional<Statement*> body) {
  return RegisterDeclarable(std::unique_ptr<Builtin>(
      new Builtin(std::move(external_name), std::move(readable_name), kind,
                  std::move(signature), body)));
}

Builtin* Declarations::DeclareBuiltin(const std::string& name,
                                      Builtin::Kind kind,
                                      const Signature& signature,

                                      base::Optional<Statement*> body) {
  CheckAlreadyDeclared<Builtin>(name, "builtin");
  return Declare(name, CreateBuiltin(name, name, kind, signature, body));
}

RuntimeFunction* Declarations::DeclareRuntimeFunction(
    const std::string& name, const Signature& signature) {
  CheckAlreadyDeclared<RuntimeFunction>(name, "runtime function");
  return Declare(name, RegisterDeclarable(std::unique_ptr<RuntimeFunction>(
                           new RuntimeFunction(name, signature))));
}

void Declarations::DeclareExternConstant(Identifier* name, const Type* type,
                                         std::string value) {
  CheckAlreadyDeclared<Value>(name->value, "constant");
  Declare(name->value, std::unique_ptr<ExternConstant>(
                           new ExternConstant(name, type, value)));
}

NamespaceConstant* Declarations::DeclareNamespaceConstant(Identifier* name,
                                                          const Type* type,
                                                          Expression* body) {
  CheckAlreadyDeclared<Value>(name->value, "constant");
  std::string external_name = GlobalContext::MakeUniqueName(name->value);
  std::unique_ptr<NamespaceConstant> namespaceConstant(
      new NamespaceConstant(name, std::move(external_name), type, body));
  NamespaceConstant* result = namespaceConstant.get();
  Declare(name->value, std::move(namespaceConstant));
  return result;
}

GenericCallable* Declarations::DeclareGenericCallable(
    const std::string& name, GenericCallableDeclaration* ast_node) {
  return Declare(name, std::unique_ptr<GenericCallable>(
                           new GenericCallable(name, ast_node)));
}

GenericType* Declarations::DeclareGenericType(
    const std::string& name, GenericTypeDeclaration* ast_node) {
  return Declare(name,
                 std::unique_ptr<GenericType>(new GenericType(name, ast_node)));
}

std::string Declarations::GetGeneratedCallableName(
    const std::string& name, const TypeVector& specialized_types) {
  std::string result = name;
  for (auto type : specialized_types) {
    result += "_" + type->SimpleName();
  }
  return result;
}

Macro* Declarations::DeclareOperator(const std::string& name, Macro* m) {
  GlobalContext::GetDefaultNamespace()->AddDeclarable(name, m);
  return m;
}

}  // namespace torque
}  // namespace internal
}  // namespace v8
