//===-- CxxModuleHandler.cpp ----------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "Plugins/ExpressionParser/Clang/CxxModuleHandler.h"
#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"

#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Log.h"
#include "clang/Sema/Lookup.h"
#include "llvm/Support/Error.h"
#include <optional>

using namespace lldb_private;
using namespace clang;

CxxModuleHandler::CxxModuleHandler(ASTImporter &importer, ASTContext *target)
    : m_importer(&importer),
      m_sema(TypeSystemClang::GetASTContext(target)->getSema()) {

  std::initializer_list<const char *> supported_names = {
      // containers
      "array",
      "deque",
      "forward_list",
      "list",
      "queue",
      "stack",
      "vector",
      // pointers
      "shared_ptr",
      "unique_ptr",
      "weak_ptr",
      // iterator
      "move_iterator",
      "__wrap_iter",
      // utility
      "allocator",
      "pair",
  };
  m_supported_templates.insert_range(supported_names);
}

/// Builds a list of scopes that point into the given context.
///
/// \param sema The sema that will be using the scopes.
/// \param ctxt The context that the scope should look into.
/// \param result A list of scopes. The scopes need to be freed by the caller
///               (except the TUScope which is owned by the sema).
static void makeScopes(Sema &sema, DeclContext *ctxt,
                       std::vector<Scope *> &result) {
  // FIXME: The result should be a list of unique_ptrs, but the TUScope makes
  // this currently impossible as it's owned by the Sema.

  if (auto parent = ctxt->getParent()) {
    makeScopes(sema, parent, result);

    Scope *scope =
        new Scope(result.back(), Scope::DeclScope, sema.getDiagnostics());
    scope->setEntity(ctxt);
    result.push_back(scope);
  } else
    result.push_back(sema.TUScope);
}

/// Uses the Sema to look up the given name in the given DeclContext.
static std::unique_ptr<LookupResult>
emulateLookupInCtxt(Sema &sema, llvm::StringRef name, DeclContext *ctxt) {
  IdentifierInfo &ident = sema.getASTContext().Idents.get(name);

  std::unique_ptr<LookupResult> lookup_result;
  lookup_result = std::make_unique<LookupResult>(sema, DeclarationName(&ident),
                                                 SourceLocation(),
                                                 Sema::LookupOrdinaryName);

  // Usually during parsing we already encountered the scopes we would use. But
  // here don't have these scopes so we have to emulate the behavior of the
  // Sema during parsing.
  std::vector<Scope *> scopes;
  makeScopes(sema, ctxt, scopes);

  // Now actually perform the lookup with the sema.
  sema.LookupName(*lookup_result, scopes.back());

  // Delete all the allocated scopes beside the translation unit scope (which
  // has depth 0).
  for (Scope *s : scopes)
    if (s->getDepth() != 0)
      delete s;

  return lookup_result;
}

/// Error class for handling problems when finding a certain DeclContext.
struct MissingDeclContext : public llvm::ErrorInfo<MissingDeclContext> {

  static char ID;

  MissingDeclContext(DeclContext *context, std::string error)
      : m_context(context), m_error(error) {}

  DeclContext *m_context;
  std::string m_error;

  void log(llvm::raw_ostream &OS) const override {
    OS << llvm::formatv("error when reconstructing context of kind {0}:{1}",
                        m_context->getDeclKindName(), m_error);
  }

  std::error_code convertToErrorCode() const override {
    return llvm::inconvertibleErrorCode();
  }
};

char MissingDeclContext::ID = 0;

/// Given a foreign decl context, this function finds the equivalent local
/// decl context in the ASTContext of the given Sema. Potentially deserializes
/// decls from the 'std' module if necessary.
static llvm::Expected<DeclContext *>
getEqualLocalDeclContext(Sema &sema, DeclContext *foreign_ctxt) {

  // Inline namespaces don't matter for lookups, so let's skip them.
  while (foreign_ctxt && foreign_ctxt->isInlineNamespace())
    foreign_ctxt = foreign_ctxt->getParent();

  // If the foreign context is the TU, we just return the local TU.
  if (foreign_ctxt->isTranslationUnit())
    return sema.getASTContext().getTranslationUnitDecl();

  // Recursively find/build the parent DeclContext.
  llvm::Expected<DeclContext *> parent =
      getEqualLocalDeclContext(sema, foreign_ctxt->getParent());
  if (!parent)
    return parent;

  // We currently only support building namespaces.
  if (foreign_ctxt->isNamespace()) {
    NamedDecl *ns = llvm::cast<NamedDecl>(foreign_ctxt);
    llvm::StringRef ns_name = ns->getName();

    auto lookup_result = emulateLookupInCtxt(sema, ns_name, *parent);
    for (NamedDecl *named_decl : *lookup_result) {
      if (DeclContext *DC = llvm::dyn_cast<DeclContext>(named_decl))
        return DC->getPrimaryContext();
    }
    return llvm::make_error<MissingDeclContext>(
        foreign_ctxt,
        "Couldn't find namespace " + ns->getQualifiedNameAsString());
  }

  return llvm::make_error<MissingDeclContext>(foreign_ctxt, "Unknown context ");
}

/// Returns true iff tryInstantiateStdTemplate supports instantiating a template
/// with the given template arguments.
static bool templateArgsAreSupported(ArrayRef<TemplateArgument> a) {
  for (const TemplateArgument &arg : a) {
    switch (arg.getKind()) {
    case TemplateArgument::Type:
    case TemplateArgument::Integral:
      break;
    default:
      // TemplateArgument kind hasn't been handled yet.
      return false;
    }
  }
  return true;
}

/// Constructor function for Clang declarations. Ensures that the created
/// declaration is registered with the ASTImporter.
template <typename T, typename... Args>
T *createDecl(ASTImporter &importer, Decl *from_d, Args &&... args) {
  T *to_d = T::Create(std::forward<Args>(args)...);
  importer.RegisterImportedDecl(from_d, to_d);
  return to_d;
}

std::optional<Decl *> CxxModuleHandler::tryInstantiateStdTemplate(Decl *d) {
  Log *log = GetLog(LLDBLog::Expressions);

  // If we don't have a template to instiantiate, then there is nothing to do.
  auto td = dyn_cast<ClassTemplateSpecializationDecl>(d);
  if (!td)
    return std::nullopt;

  // We only care about templates in the std namespace.
  if (!td->getDeclContext()->isStdNamespace())
    return std::nullopt;

  // We have a list of supported template names.
  if (!m_supported_templates.contains(td->getName()))
    return std::nullopt;

  // Early check if we even support instantiating this template. We do this
  // before we import anything into the target AST.
  auto &foreign_args = td->getTemplateInstantiationArgs();
  if (!templateArgsAreSupported(foreign_args.asArray()))
    return std::nullopt;

  // Find the local DeclContext that corresponds to the DeclContext of our
  // decl we want to import.
  llvm::Expected<DeclContext *> to_context =
      getEqualLocalDeclContext(*m_sema, td->getDeclContext());
  if (!to_context) {
    LLDB_LOG_ERROR(log, to_context.takeError(),
                   "Got error while searching equal local DeclContext for decl "
                   "'{1}':\n{0}",
                   td->getName());
    return std::nullopt;
  }

  // Look up the template in our local context.
  std::unique_ptr<LookupResult> lookup =
      emulateLookupInCtxt(*m_sema, td->getName(), *to_context);

  ClassTemplateDecl *new_class_template = nullptr;
  for (auto LD : *lookup) {
    if ((new_class_template = dyn_cast<ClassTemplateDecl>(LD)))
      break;
  }
  if (!new_class_template)
    return std::nullopt;

  // Import the foreign template arguments.
  llvm::SmallVector<TemplateArgument, 4> imported_args;

  // If this logic is changed, also update templateArgsAreSupported.
  for (const TemplateArgument &arg : foreign_args.asArray()) {
    switch (arg.getKind()) {
    case TemplateArgument::Type: {
      llvm::Expected<QualType> type = m_importer->Import(arg.getAsType());
      if (!type) {
        LLDB_LOG_ERROR(log, type.takeError(), "Couldn't import type: {0}");
        return std::nullopt;
      }
      imported_args.push_back(
          TemplateArgument(*type, /*isNullPtr*/ false, arg.getIsDefaulted()));
      break;
    }
    case TemplateArgument::Integral: {
      llvm::APSInt integral = arg.getAsIntegral();
      llvm::Expected<QualType> type =
          m_importer->Import(arg.getIntegralType());
      if (!type) {
        LLDB_LOG_ERROR(log, type.takeError(), "Couldn't import type: {0}");
        return std::nullopt;
      }
      imported_args.push_back(TemplateArgument(d->getASTContext(), integral,
                                               *type, arg.getIsDefaulted()));
      break;
    }
    default:
      assert(false && "templateArgsAreSupported not updated?");
    }
  }

  // Find the class template specialization declaration that
  // corresponds to these arguments.
  void *InsertPos = nullptr;
  ClassTemplateSpecializationDecl *result =
      new_class_template->findSpecialization(imported_args, InsertPos);

  if (result) {
    // We found an existing specialization in the module that fits our arguments
    // so we can treat it as the result and register it with the ASTImporter.
    m_importer->RegisterImportedDecl(d, result);
    return result;
  }

  // Instantiate the template.
  result = createDecl<ClassTemplateSpecializationDecl>(
      *m_importer, d, m_sema->getASTContext(),
      new_class_template->getTemplatedDecl()->getTagKind(),
      new_class_template->getDeclContext(),
      new_class_template->getTemplatedDecl()->getLocation(),
      new_class_template->getLocation(), new_class_template, imported_args,
      td->hasStrictPackMatch(),
      /*PrevDecl=*/nullptr);

  new_class_template->AddSpecialization(result, InsertPos);
  if (new_class_template->isOutOfLine())
    result->setLexicalDeclContext(
        new_class_template->getLexicalDeclContext());
  return result;
}

std::optional<Decl *> CxxModuleHandler::Import(Decl *d) {
  if (!isValid())
    return {};

  return tryInstantiateStdTemplate(d);
}
