// Part of the Crubit project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#include "rs_bindings_from_cc/importers/function.h"

#include <algorithm>
#include <memory>
#include <optional>
#include <set>
#include <string>
#include <utility>
#include <vector>

#include "absl/log/check.h"
#include "absl/status/statusor.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/substitute.h"
#include "lifetime_annotations/lifetime.h"
#include "lifetime_annotations/lifetime_annotations.h"
#include "lifetime_annotations/lifetime_error.h"
#include "lifetime_annotations/lifetime_symbol_table.h"
#include "lifetime_annotations/type_lifetimes.h"
#include "rs_bindings_from_cc/ast_util.h"
#include "rs_bindings_from_cc/bazel_types.h"
#include "rs_bindings_from_cc/ir.h"
#include "rs_bindings_from_cc/recording_diagnostic_consumer.h"
#include "clang/AST/Attr.h"
#include "clang/AST/Attrs.inc"
#include "clang/AST/DeclarationName.h"
#include "clang/AST/Type.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/Specifiers.h"
#include "clang/Sema/Sema.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Error.h"

namespace crubit {

static bool IsInStdNamespace(const clang::FunctionDecl* decl) {
  const clang::DeclContext* context = decl->getDeclContext();
  while (context) {
    if (context->isStdNamespace()) {
      return true;
    }
    context = context->getParent();
  }
  return false;
}

Identifier FunctionDeclImporter::GetTranslatedParamName(
    const clang::ParmVarDecl* param_decl) {
  int param_pos = param_decl->getFunctionScopeIndex();
  absl::StatusOr<Identifier> name = ictx_.GetTranslatedIdentifier(param_decl);
  if (!name.ok()) {
    return {Identifier(absl::StrCat("__param_", param_pos))};
  }
  if (auto* sttpt =
          param_decl->getType()->getAs<clang::SubstTemplateTypeParmType>();
      sttpt && sttpt->getReplacedParameter()->isParameterPack()) {
    // Avoid giving the same name to all parameters expanded from a pack.
    return {Identifier(absl::StrCat("__", name->Ident(), "_", param_pos))};
  }
  return *name;
}

std::optional<IR::Item> FunctionDeclImporter::Import(
    clang::FunctionDecl* function_decl) {
  if (!ictx_.IsFromCurrentTarget(function_decl)) return std::nullopt;
  if (function_decl->isDeleted()) return std::nullopt;

  clang::FunctionDecl* template_decl_for_method =
      function_decl->getInstantiatedFromMemberFunction();
  if (IsInStdNamespace(function_decl)) {
    if (clang::IdentifierInfo* id = function_decl->getIdentifier();
        id != nullptr && id->getName().find("__") != llvm::StringRef::npos) {
      return ictx_.ImportUnsupportedItem(
          function_decl,
          "Internal functions from the standard library are not supported");
    }
  }
  // Method is private, we don't need to import it.
  if (auto* method_decl =
          clang::dyn_cast<clang::CXXMethodDecl>(function_decl)) {
    switch (method_decl->getAccess()) {
      case clang::AS_public:
        break;
      case clang::AS_protected:
      case clang::AS_private:
      case clang::AS_none:
        // No need for IR to include Func representing private methods.
        // TODO(lukasza): Revisit this for protected methods.
        return std::nullopt;
    }
  }

  // We should only import methods of class template specializations
  // that can be instantiated: the template may spell out the method,
  // but it's not guaranteed to be instantiable for the template parameter(s);
  // importing an un-instantiable method causes Crubit to generate a thunk to
  // invoke this method, which triggers instantiation when compiling the
  // generated bindings, which fails the build.
  if (template_decl_for_method) {
    // Some methods in STL are explicitly marked with
    // `__attribute__((exclude_from_explicit_instantiation))`, and attempt to
    // instantiate them may crash clang, so we skip them for now.
    bool skip_instantiation = false;
    if (template_decl_for_method->hasAttrs()) {
      skip_instantiation = std::any_of(
          function_decl->attr_begin(), function_decl->attr_end(),
          [](auto attr) {
            return clang::isa<clang::ExcludeFromExplicitInstantiationAttr>(
                attr);
          });
    }
    if (!function_decl->isDefined() && !skip_instantiation) {
      // Here, we have the option to instantiate the function
      // definition recursively, that is, to instantiate the function
      // templates invoked within the (templated) body. This checks the
      // validity of the function template more thoroughly than simply
      // ensuring the type of the invoked function template is correct: e.g.,
      // If `Recursive` is set, a diagnostic would be emitted if the function
      // template invoked in the body fails to instantiate (e.g., due to a
      // static_assert) but still passes type checking. However, this has the
      // side effect of actually instantiating the invoked function template
      // and the invoked function template would be considered "defined", so
      // we wouldn't be able to get diagnostics when actually importing the
      // invoked function template.
      // TODO(b/248542210): Propagate the validity check of function templates
      // in a function template body.
      // TODO(b/248542210): `clang::Sema::InstantiateClassMembers` checks more
      // constraints (than here) when instantiating the methods, consider use
      // that API instead (and avoid calling `InstantiateFunctionDefinition`
      // here). We don't use it now because we cannot clearly attribute
      // emitted diagnostics to a member decl (we need diagnostics because the
      // decl may be considered valid `!decl->isInvalidDecl()` while its
      // instantiation may fail.)
      auto point_of_instantiation = function_decl->getPointOfInstantiation();
      // Point of instantiation is invalid if Crubit is eagerly
      // instantiating a method of a class template specialization.
      if (point_of_instantiation.isInvalid()) {
        point_of_instantiation = function_decl->getLocation();
      }
      crubit::RecordingDiagnosticConsumer diagnostic_recorder =
          crubit::RecordDiagnostics(ictx_.sema_.getDiagnostics(), [&] {
            ictx_.sema_.InstantiateFunctionDefinition(point_of_instantiation,
                                                      function_decl);
          });
      std::string diagnostics = diagnostic_recorder.ConcatenatedDiagnostics(
          ": Diagnostics emitted:\n");
      if (diagnostic_recorder.getNumErrors() != 0) {
        // Clang considers the function decl valid even fatal diagnostics is
        // emitted during instantiation. However, such diagnostics would fail
        // compilation of generated bindings, so it's invalid as far as Crubit
        // is concerned, thus set it as invalid here.
        function_decl->setInvalidDecl();
        return ictx_.ImportUnsupportedItem(
            function_decl,
            absl::StrCat("Failed to instantiate the function/method template",
                         diagnostics));
      }
    }
  }
  if (function_decl->isInvalidDecl()) {
    return ictx_.ImportUnsupportedItem(
        function_decl, "Function declaration is considered invalid");
  }

  clang::tidy::lifetimes::LifetimeSymbolTable lifetime_symbol_table;
  std::optional<clang::tidy::lifetimes::FunctionLifetimes> lifetimes;
  llvm::Expected<clang::tidy::lifetimes::FunctionLifetimes> lifetimes_or_err =
      clang::tidy::lifetimes::GetLifetimeAnnotations(
          function_decl, *ictx_.invocation_.lifetime_context_,
          &lifetime_symbol_table);
  if (lifetimes_or_err) {
    lifetimes = std::move(*lifetimes_or_err);
  } else {
    using clang::tidy::lifetimes::LifetimeError;
    llvm::Error remaining_err = llvm::handleErrors(
        lifetimes_or_err.takeError(),
        [](std::unique_ptr<LifetimeError> lifetime_err) -> llvm::Error {
          switch (lifetime_err->type()) {
            case LifetimeError::Type::ElisionNotEnabled:
            case LifetimeError::Type::CannotElideOutputLifetimes:
              // If elision is not enabled or output lifetimes cannot be
              // elided, we want to import the function with raw lifetime-less
              // pointers. Just return success here; this will leave the
              // `lifetimes` optional empty, and we will then handle this
              // accordingly below.
              return llvm::Error::success();
              break;
            default:
              return llvm::Error(std::move(lifetime_err));
              break;
          }
        });
    if (remaining_err) {
      return ictx_.ImportUnsupportedItem(
          function_decl, llvm::toString(std::move(remaining_err)));
    }
  }

  absl::StatusOr<UnqualifiedIdentifier> translated_name =
      ictx_.GetTranslatedName(function_decl);
  if (!translated_name.ok()) {
    return ictx_.ImportUnsupportedItem(
        function_decl, absl::StrCat("Function name is not supported: ",
                                    translated_name.status().message()));
  }

  std::vector<FuncParam> params;
  std::set<std::string> errors;
  auto add_error = [&errors](std::string msg) {
    auto result = errors.insert(std::move(msg));
    CHECK(result.second) << "Duplicated error message";
  };
  if (auto* method_decl =
          clang::dyn_cast<clang::CXXMethodDecl>(function_decl)) {
    if (!ictx_.HasBeenAlreadySuccessfullyImported(method_decl->getParent())) {
      return ictx_.ImportUnsupportedItem(function_decl,
                                         "Couldn't import the parent");
    }

    // non-static member functions receive an implicit `this` parameter.
    if (method_decl->isInstance()) {
      const clang::tidy::lifetimes::ValueLifetimes* this_lifetimes = nullptr;
      if (lifetimes) {
        this_lifetimes = &lifetimes->GetThisLifetimes();
      }
      auto param_type =
          ictx_.ConvertQualType(method_decl->getThisType(), this_lifetimes,
                                std::optional<clang::RefQualifierKind>(
                                    method_decl->getRefQualifier()),
                                /*nullable=*/false);
      if (!param_type.ok()) {
        add_error(absl::StrCat("`this` parameter is not supported: ",
                               param_type.status().message()));
      } else {
        params.push_back(
            {.type = *std::move(param_type),
             .identifier = Identifier("__this"),
             // TODO(b/319524852): catch `[[clang::lifetimbound]]` on `this`.
             .unknown_attr = {}});
      }
    }
  }

  if (lifetimes) {
    CHECK(lifetimes->IsValidForDecl(function_decl));
  }

  for (unsigned i = 0; i < function_decl->getNumParams(); ++i) {
    const clang::ParmVarDecl* param = function_decl->getParamDecl(i);
    const clang::tidy::lifetimes::ValueLifetimes* param_lifetimes = nullptr;
    if (lifetimes) {
      param_lifetimes = &lifetimes->GetParamLifetimes(i);
    }
    auto param_type =
        ictx_.ConvertQualType(param->getType(), param_lifetimes, std::nullopt);
    if (!param_type.ok()) {
      add_error(absl::Substitute("Parameter #$0 is not supported: $1", i,
                                 param_type.status().message()));
      continue;
    }

    std::optional<Identifier> param_name = GetTranslatedParamName(param);
    CHECK(param_name.has_value());  // No known failure cases.
    params.push_back({.type = *param_type,
                      .identifier = *std::move(param_name),
                      .unknown_attr = CollectUnknownAttrs(*param)});
  }

  bool undeduced_return_type =
      function_decl->getReturnType()->isUndeducedType();
  if (undeduced_return_type) {
    // Use a custom diagnoser as the `DeduceReturnType` call may fail, which
    // is OK if this is a method of a class template, since Crubit
    // instantiates the members of the class templates eagerly.
    crubit::RecordingDiagnosticConsumer diagnostic_recorder =
        crubit::RecordDiagnostics(ictx_.sema_.getDiagnostics(), [&] {
          undeduced_return_type = ictx_.sema_.DeduceReturnType(
              function_decl, function_decl->getLocation());
        });
    if (undeduced_return_type) {
      add_error(absl::StrCat("Couldn't deduce the return type",
                             diagnostic_recorder.ConcatenatedDiagnostics(
                                 ": Diagnostics emitted:\n")));
    }
  }
  absl::StatusOr<MappedType> return_type;
  if (!undeduced_return_type) {
    const clang::tidy::lifetimes::ValueLifetimes* return_lifetimes = nullptr;
    if (lifetimes) {
      return_lifetimes = &lifetimes->GetReturnLifetimes();
    }
    return_type = ictx_.ConvertQualType(function_decl->getReturnType(),
                                        return_lifetimes, std::nullopt);
    if (!return_type.ok()) {
      add_error(absl::StrCat("Return type is not supported: ",
                             return_type.status().message()));
    }
  }

  llvm::DenseSet<clang::tidy::lifetimes::Lifetime> all_free_lifetimes;
  if (lifetimes) {
    all_free_lifetimes = lifetimes->AllFreeLifetimes();
  }

  std::vector<LifetimeName> lifetime_params;
  for (clang::tidy::lifetimes::Lifetime lifetime : all_free_lifetimes) {
    std::optional<llvm::StringRef> name =
        lifetime_symbol_table.LookupLifetime(lifetime);
    CHECK(name.has_value());
    lifetime_params.push_back(
        {.name = name->str(), .id = LifetimeId(lifetime.Id())});
  }
  llvm::sort(lifetime_params,
             [](const LifetimeName& l1, const LifetimeName& l2) {
               return l1.name < l2.name;
             });

  std::optional<MemberFuncMetadata> member_func_metadata;
  if (auto* method_decl =
          clang::dyn_cast<clang::CXXMethodDecl>(function_decl)) {
    std::optional<MemberFuncMetadata::InstanceMethodMetadata> instance_metadata;
    if (method_decl->isInstance()) {
      MemberFuncMetadata::ReferenceQualification reference;
      switch (method_decl->getRefQualifier()) {
        case clang::RQ_LValue:
          reference = MemberFuncMetadata::kLValue;
          break;
        case clang::RQ_RValue:
          reference = MemberFuncMetadata::kRValue;
          break;
        case clang::RQ_None:
          reference = MemberFuncMetadata::kUnqualified;
          break;
      }
      instance_metadata = MemberFuncMetadata::InstanceMethodMetadata{
          .reference = reference,
          .is_const = method_decl->isConst(),
          .is_virtual = method_decl->isVirtual(),
      };
    }

    member_func_metadata = MemberFuncMetadata{
        .record_id = ictx_.GenerateItemId(method_decl->getParent()),
        .instance_method_metadata = instance_metadata};
  }

  if (!errors.empty()) {
    return ictx_.ImportUnsupportedItem(function_decl, errors);
  }

  bool has_c_calling_convention =
      function_decl->getType()->getAs<clang::FunctionType>()->getCallConv() ==
      clang::CC_C;
  bool is_member_or_descendant_of_class_template =
      IsFullClassTemplateSpecializationOrChild(function_decl);

  std::optional<std::string> doc_comment = ictx_.GetComment(function_decl);
  if (!doc_comment.has_value() && is_member_or_descendant_of_class_template) {
    // Despite `is_member_or_descendant_of_class_template` check above, we are
    // not guaranteed that a `func_pattern` exists below.  For example, it may
    // be missing when `function_decl` is an implicitly defined constructor of
    // a class template -- such decls are generated, not instantiated.
    if (clang::FunctionDecl* func_pattern =
            function_decl->getTemplateInstantiationPattern()) {
      doc_comment = ictx_.GetComment(func_pattern);
    }
  }

  std::optional<std::string> nodiscard;
  std::optional<std::string> deprecated;
  std::optional<std::string> unknown_attr =
      CollectUnknownAttrs(*function_decl, [&](const clang::Attr& attr) {
        if (auto* unused_attr =
                clang::dyn_cast<clang::WarnUnusedResultAttr>(&attr)) {
          nodiscard.emplace(unused_attr->getMessage());
          return true;
        } else if (auto* deprecated_attr =
                       clang::dyn_cast<clang::DeprecatedAttr>(&attr)) {
          deprecated.emplace(deprecated_attr->getMessage());
          return true;
        } else if (clang::isa<clang::NoReturnAttr>(attr)) {
          return true;  // we call isNoReturn below, instead
        } else if (clang::isa<clang::NoThrowAttr>(attr)) {
          // nothrow attributes don't affect Rust.
          return true;
        }
        return false;
      });

  // Silence ClangTidy, checked above: calling `add_error` if
  // `!return_type.ok()` and returning early if `!errors.empty()`.
  CHECK_OK(return_type);

  auto enclosing_item_id = ictx_.GetEnclosingItemId(function_decl);
  if (!enclosing_item_id.ok()) {
    return ictx_.ImportUnsupportedItem(
        function_decl, std::string(enclosing_item_id.status().message()));
  }

  return Func{
      .name = *translated_name,
      .owning_target = ictx_.GetOwningTarget(function_decl),
      .doc_comment = std::move(doc_comment),
      .mangled_name = ictx_.GetMangledName(function_decl),
      .return_type = *return_type,
      .params = std::move(params),
      .lifetime_params = std::move(lifetime_params),
      .is_inline = function_decl->isInlined(),
      .member_func_metadata = std::move(member_func_metadata),
      .is_extern_c = function_decl->isExternC(),
      .is_noreturn = function_decl->isNoReturn(),
      .nodiscard = std::move(nodiscard),
      .deprecated = std::move(deprecated),
      .unknown_attr = std::move(unknown_attr),
      .has_c_calling_convention = has_c_calling_convention,
      .is_member_or_descendant_of_class_template =
          is_member_or_descendant_of_class_template,
      .source_loc = ictx_.ConvertSourceLocation(function_decl->getBeginLoc()),
      .id = ictx_.GenerateItemId(function_decl),
      .enclosing_item_id = *std::move(enclosing_item_id),
  };
}

}  // namespace crubit
