//===--- CrtpConstructorAccessibilityCheck.cpp - clang-tidy ---------------===//
//
// 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 "CrtpConstructorAccessibilityCheck.h"
#include "../utils/LexerUtils.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"

using namespace clang::ast_matchers;

namespace clang::tidy::bugprone {

static bool hasPrivateConstructor(const CXXRecordDecl *RD) {
  return llvm::any_of(RD->ctors(), [](const CXXConstructorDecl *Ctor) {
    return Ctor->getAccess() == AS_private;
  });
}

static bool isDerivedParameterBefriended(const CXXRecordDecl *CRTP,
                                         const NamedDecl *Param) {
  return llvm::any_of(CRTP->friends(), [&](const FriendDecl *Friend) {
    const TypeSourceInfo *const FriendType = Friend->getFriendType();
    if (!FriendType) {
      return false;
    }

    const auto *const TTPT =
        dyn_cast<TemplateTypeParmType>(FriendType->getType());

    return TTPT && TTPT->getDecl() == Param;
  });
}

static bool isDerivedClassBefriended(const CXXRecordDecl *CRTP,
                                     const CXXRecordDecl *Derived) {
  return llvm::any_of(CRTP->friends(), [&](const FriendDecl *Friend) {
    const TypeSourceInfo *const FriendType = Friend->getFriendType();
    if (!FriendType) {
      return false;
    }

    return FriendType->getType()->getAsCXXRecordDecl() == Derived;
  });
}

static const NamedDecl *
getDerivedParameter(const ClassTemplateSpecializationDecl *CRTP,
                    const CXXRecordDecl *Derived) {
  size_t Idx = 0;
  const bool AnyOf = llvm::any_of(
      CRTP->getTemplateArgs().asArray(), [&](const TemplateArgument &Arg) {
        ++Idx;
        return Arg.getKind() == TemplateArgument::Type &&
               Arg.getAsType()->getAsCXXRecordDecl() == Derived;
      });

  return AnyOf ? CRTP->getSpecializedTemplate()
                     ->getTemplateParameters()
                     ->getParam(Idx - 1)
               : nullptr;
}

static std::vector<FixItHint>
hintMakeCtorPrivate(const CXXConstructorDecl *Ctor,
                    const std::string &OriginalAccess) {
  std::vector<FixItHint> Hints;

  Hints.emplace_back(FixItHint::CreateInsertion(
      Ctor->getBeginLoc().getLocWithOffset(-1), "private:\n"));

  const ASTContext &ASTCtx = Ctor->getASTContext();
  const SourceLocation CtorEndLoc =
      Ctor->isExplicitlyDefaulted()
          ? utils::lexer::findNextTerminator(Ctor->getEndLoc(),
                                             ASTCtx.getSourceManager(),
                                             ASTCtx.getLangOpts())
          : Ctor->getEndLoc();
  Hints.emplace_back(FixItHint::CreateInsertion(
      CtorEndLoc.getLocWithOffset(1), '\n' + OriginalAccess + ':' + '\n'));

  return Hints;
}

void CrtpConstructorAccessibilityCheck::registerMatchers(MatchFinder *Finder) {
  Finder->addMatcher(
      classTemplateSpecializationDecl(
          decl().bind("crtp"),
          hasAnyTemplateArgument(refersToType(recordType(hasDeclaration(
              cxxRecordDecl(
                  isDerivedFrom(cxxRecordDecl(equalsBoundNode("crtp"))))
                  .bind("derived")))))),
      this);
}

void CrtpConstructorAccessibilityCheck::check(
    const MatchFinder::MatchResult &Result) {
  const auto *CRTPInstantiation =
      Result.Nodes.getNodeAs<ClassTemplateSpecializationDecl>("crtp");
  const auto *DerivedRecord = Result.Nodes.getNodeAs<CXXRecordDecl>("derived");
  const CXXRecordDecl *CRTPDeclaration =
      CRTPInstantiation->getSpecializedTemplate()->getTemplatedDecl();

  if (!CRTPDeclaration->hasDefinition()) {
    return;
  }

  const auto *DerivedTemplateParameter =
      getDerivedParameter(CRTPInstantiation, DerivedRecord);

  assert(DerivedTemplateParameter &&
         "No template parameter corresponds to the derived class of the CRTP.");

  bool NeedsFriend = !isDerivedParameterBefriended(CRTPDeclaration,
                                                   DerivedTemplateParameter) &&
                     !isDerivedClassBefriended(CRTPDeclaration, DerivedRecord);

  const FixItHint HintFriend = FixItHint::CreateInsertion(
      CRTPDeclaration->getBraceRange().getEnd(),
      "friend " + DerivedTemplateParameter->getNameAsString() + ';' + '\n');

  if (hasPrivateConstructor(CRTPDeclaration) && NeedsFriend) {
    diag(CRTPDeclaration->getLocation(),
         "the CRTP cannot be constructed from the derived class; consider "
         "declaring the derived class as friend")
        << HintFriend;
  }

  auto WithFriendHintIfNeeded =
      [&](const DiagnosticBuilder &Diag,
          bool NeedsFriend) -> const DiagnosticBuilder & {
    if (NeedsFriend)
      Diag << HintFriend;

    return Diag;
  };

  if (!CRTPDeclaration->hasUserDeclaredConstructor()) {
    const bool IsStruct = CRTPDeclaration->isStruct();

    WithFriendHintIfNeeded(
        diag(CRTPDeclaration->getLocation(),
             "the implicit default constructor of the CRTP is publicly "
             "accessible; consider making it private%select{| and declaring "
             "the derived class as friend}0")
            << NeedsFriend
            << FixItHint::CreateInsertion(
                   CRTPDeclaration->getBraceRange().getBegin().getLocWithOffset(
                       1),
                   (IsStruct ? "\nprivate:\n" : "\n") +
                       CRTPDeclaration->getNameAsString() + "() = default;\n" +
                       (IsStruct ? "public:\n" : "")),
        NeedsFriend);
  }

  for (auto &&Ctor : CRTPDeclaration->ctors()) {
    if (Ctor->getAccess() == AS_private)
      continue;

    const bool IsPublic = Ctor->getAccess() == AS_public;
    const std::string Access = IsPublic ? "public" : "protected";

    WithFriendHintIfNeeded(
        diag(Ctor->getLocation(),
             "%0 constructor allows the CRTP to be %select{inherited "
             "from|constructed}1 as a regular template class; consider making "
             "it private%select{| and declaring the derived class as friend}2")
            << Access << IsPublic << NeedsFriend
            << hintMakeCtorPrivate(Ctor, Access),
        NeedsFriend);
  }
}

bool CrtpConstructorAccessibilityCheck::isLanguageVersionSupported(
    const LangOptions &LangOpts) const {
  return LangOpts.CPlusPlus11;
}
} // namespace clang::tidy::bugprone
