// 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/ast_util.h"

#include <optional>
#include <string>

#include "absl/functional/function_ref.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "clang/AST/Attr.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/Type.h"
#include "clang/Basic/AttrKinds.h"
#include "clang/Basic/LLVM.h"

namespace crubit {

bool IsFullClassTemplateSpecializationOrChild(const clang::Decl* decl) {
  if (clang::isa<clang::ClassTemplatePartialSpecializationDecl>(decl)) {
    return false;
  }
  if (clang::isa<clang::ClassTemplateSpecializationDecl>(decl)) {
    return true;
  }

  if (const auto* decl_context = decl->getDeclContext()) {
    return IsFullClassTemplateSpecializationOrChild(
        clang::dyn_cast<clang::Decl>(decl_context));
  }

  return false;
}

std::optional<std::string> CollectUnknownAttrs(
    const clang::Decl& decl,
    absl::FunctionRef<bool(const clang::Attr&)> is_known) {
  std::optional<std::string> unknown_attr;
  if (!decl.hasAttrs()) {
    // Surprisingly, getAttrs() does not return an empty vec if there are no
    // attrs, it crashes.
    return unknown_attr;
  }
  for (clang::Attr* attr : decl.getAttrs()) {
    if (is_known(*attr)) {
      continue;
    }
    if (unknown_attr.has_value()) {
      absl::StrAppend(&*unknown_attr, ", ");
    } else {
      unknown_attr.emplace("");
    }
    absl::StrAppend(&*unknown_attr, attr->getAttrName()
                                        ? attr->getNormalizedFullName()
                                        : attr->getSpelling());
  }
  return unknown_attr;
}

absl::string_view DebugAttrName(clang::attr::Kind attr_kind) {
  // TODO(jeanpierreda): Give some more human-readable name, e.g. using
  // ParsedAttrInfo::getAllBuiltin.  Unfortunately, we don't have a TypeLoc,
  // so we only have access to a Kind, which doesn't specify how it is spelled.
  //
  // For now, we use the symbol name, and prefix it with `clang::attr` to make
  // it obvious it's an internal symbol and not something the user typed.
  switch (attr_kind) {
    // (Yes, the X-macro is really the only way to do it. Party like it's 1969!)
#define ATTR(X)        \
  case clang::attr::X: \
    return "clang::attr::Kind::" #X;
#include "clang/Basic/AttrList.inc"
#undef ATTR
  }
}

std::optional<std::string> CollectUnknownTypeAttrs(
    const clang::Type& t, absl::FunctionRef<bool(clang::attr::Kind)> is_known) {
  std::optional<std::string> unknown_attr;
  const clang::Type* type = &t;
  while (const auto* attributed_type = type->getAs<clang::AttributedType>()) {
    clang::attr::Kind attr_kind = attributed_type->getAttrKind();
    if (!is_known(attr_kind)) {
      if (unknown_attr.has_value()) {
        absl::StrAppend(&*unknown_attr, ", ");
      } else {
        unknown_attr.emplace("");
      }
      absl::StrAppend(&*unknown_attr, DebugAttrName(attr_kind));
    }
    type = attributed_type->getEquivalentType().getTypePtr();
  }
  return unknown_attr;
}

}  // namespace crubit
