//===--- QualifiedAutoCheck.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 "QualifiedAutoCheck.h"
#include "../utils/LexerUtils.h"
#include "../utils/Matchers.h"
#include "../utils/OptionsUtils.h"
#include "clang/ASTMatchers/ASTMatchers.h"
#include "llvm/ADT/SmallVector.h"
#include <optional>

using namespace clang::ast_matchers;

namespace clang::tidy::readability {

namespace {

// FIXME move to ASTMatchers
AST_MATCHER_P(QualType, hasUnqualifiedType,
              ast_matchers::internal::Matcher<QualType>, InnerMatcher) {
  return InnerMatcher.matches(Node.getUnqualifiedType(), Finder, Builder);
}

enum class Qualifier { Const, Volatile, Restrict };

std::optional<Token> findQualToken(const VarDecl *Decl, Qualifier Qual,
                                   const MatchFinder::MatchResult &Result) {
  // Since either of the locs can be in a macro, use `makeFileCharRange` to be
  // sure that we have a consistent `CharSourceRange`, located entirely in the
  // source file.

  assert((Qual == Qualifier::Const || Qual == Qualifier::Volatile ||
          Qual == Qualifier::Restrict) &&
         "Invalid Qualifier");

  SourceLocation BeginLoc = Decl->getQualifierLoc().getBeginLoc();
  if (BeginLoc.isInvalid())
    BeginLoc = Decl->getBeginLoc();
  SourceLocation EndLoc = Decl->getLocation();

  CharSourceRange FileRange = Lexer::makeFileCharRange(
      CharSourceRange::getCharRange(BeginLoc, EndLoc), *Result.SourceManager,
      Result.Context->getLangOpts());

  if (FileRange.isInvalid())
    return std::nullopt;

  tok::TokenKind Tok =
      Qual == Qualifier::Const
          ? tok::kw_const
          : Qual == Qualifier::Volatile ? tok::kw_volatile : tok::kw_restrict;

  return utils::lexer::getQualifyingToken(Tok, FileRange, *Result.Context,
                                          *Result.SourceManager);
}

std::optional<SourceRange>
getTypeSpecifierLocation(const VarDecl *Var,
                         const MatchFinder::MatchResult &Result) {
  SourceRange TypeSpecifier(
      Var->getTypeSpecStartLoc(),
      Var->getTypeSpecEndLoc().getLocWithOffset(Lexer::MeasureTokenLength(
          Var->getTypeSpecEndLoc(), *Result.SourceManager,
          Result.Context->getLangOpts())));

  if (TypeSpecifier.getBegin().isMacroID() ||
      TypeSpecifier.getEnd().isMacroID())
    return std::nullopt;
  return TypeSpecifier;
}

std::optional<SourceRange> mergeReplacementRange(SourceRange &TypeSpecifier,
                                                 const Token &ConstToken) {
  if (TypeSpecifier.getBegin().getLocWithOffset(-1) == ConstToken.getEndLoc()) {
    TypeSpecifier.setBegin(ConstToken.getLocation());
    return std::nullopt;
  }
  if (TypeSpecifier.getEnd().getLocWithOffset(1) == ConstToken.getLocation()) {
    TypeSpecifier.setEnd(ConstToken.getEndLoc());
    return std::nullopt;
  }
  return SourceRange(ConstToken.getLocation(), ConstToken.getEndLoc());
}

bool isPointerConst(QualType QType) {
  QualType Pointee = QType->getPointeeType();
  assert(!Pointee.isNull() && "can't have a null Pointee");
  return Pointee.isConstQualified();
}

bool isAutoPointerConst(QualType QType) {
  QualType Pointee =
      cast<AutoType>(QType->getPointeeType().getTypePtr())->desugar();
  assert(!Pointee.isNull() && "can't have a null Pointee");
  return Pointee.isConstQualified();
}

} // namespace

QualifiedAutoCheck::QualifiedAutoCheck(StringRef Name,
                                       ClangTidyContext *Context)
    : ClangTidyCheck(Name, Context),
      AddConstToQualified(Options.get("AddConstToQualified", true)),
      AllowedTypes(
          utils::options::parseStringList(Options.get("AllowedTypes", ""))) {}

void QualifiedAutoCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
  Options.store(Opts, "AddConstToQualified", AddConstToQualified);
  Options.store(Opts, "AllowedTypes",
                utils::options::serializeStringList(AllowedTypes));
}

void QualifiedAutoCheck::registerMatchers(MatchFinder *Finder) {
  auto ExplicitSingleVarDecl =
      [](const ast_matchers::internal::Matcher<VarDecl> &InnerMatcher,
         llvm::StringRef ID) {
        return declStmt(
            unless(isInTemplateInstantiation()),
            hasSingleDecl(
                varDecl(unless(isImplicit()), InnerMatcher).bind(ID)));
      };
  auto ExplicitSingleVarDeclInTemplate =
      [](const ast_matchers::internal::Matcher<VarDecl> &InnerMatcher,
         llvm::StringRef ID) {
        return declStmt(
            isInTemplateInstantiation(),
            hasSingleDecl(
                varDecl(unless(isImplicit()), InnerMatcher).bind(ID)));
      };

  auto IsBoundToType = refersToType(equalsBoundNode("type"));
  auto UnlessFunctionType = unless(hasUnqualifiedDesugaredType(functionType()));
  auto IsAutoDeducedToPointer = [](const std::vector<StringRef> &AllowedTypes,
                                   const auto &...InnerMatchers) {
    return autoType(hasDeducedType(
        hasUnqualifiedDesugaredType(pointerType(pointee(InnerMatchers...))),
        unless(hasUnqualifiedType(
            matchers::matchesAnyListedTypeName(AllowedTypes, false))),
        unless(pointerType(pointee(hasUnqualifiedType(
            matchers::matchesAnyListedTypeName(AllowedTypes, false)))))));
  };

  Finder->addMatcher(
      ExplicitSingleVarDecl(
          hasType(IsAutoDeducedToPointer(AllowedTypes, UnlessFunctionType)),
          "auto"),
      this);

  Finder->addMatcher(
      ExplicitSingleVarDeclInTemplate(
          allOf(hasType(IsAutoDeducedToPointer(
                    AllowedTypes, hasUnqualifiedType(qualType().bind("type")),
                    UnlessFunctionType)),
                anyOf(hasAncestor(
                          functionDecl(hasAnyTemplateArgument(IsBoundToType))),
                      hasAncestor(classTemplateSpecializationDecl(
                          hasAnyTemplateArgument(IsBoundToType))))),
          "auto"),
      this);
  if (!AddConstToQualified)
    return;
  Finder->addMatcher(ExplicitSingleVarDecl(
                         hasType(pointerType(pointee(autoType()))), "auto_ptr"),
                     this);
  Finder->addMatcher(
      ExplicitSingleVarDecl(hasType(lValueReferenceType(pointee(autoType()))),
                            "auto_ref"),
      this);
}

void QualifiedAutoCheck::check(const MatchFinder::MatchResult &Result) {
  if (const auto *Var = Result.Nodes.getNodeAs<VarDecl>("auto")) {
    SourceRange TypeSpecifier;
    if (std::optional<SourceRange> TypeSpec =
            getTypeSpecifierLocation(Var, Result)) {
      TypeSpecifier = *TypeSpec;
    } else
      return;

    llvm::SmallVector<SourceRange, 4> RemoveQualifiersRange;
    auto CheckQualifier = [&](bool IsPresent, Qualifier Qual) {
      if (IsPresent) {
        std::optional<Token> Token = findQualToken(Var, Qual, Result);
        if (!Token || Token->getLocation().isMacroID())
          return true; // Disregard this VarDecl.
        if (std::optional<SourceRange> Result =
                mergeReplacementRange(TypeSpecifier, *Token))
          RemoveQualifiersRange.push_back(*Result);
      }
      return false;
    };

    bool IsLocalConst = Var->getType().isLocalConstQualified();
    bool IsLocalVolatile = Var->getType().isLocalVolatileQualified();
    bool IsLocalRestrict = Var->getType().isLocalRestrictQualified();

    if (CheckQualifier(IsLocalConst, Qualifier::Const) ||
        CheckQualifier(IsLocalVolatile, Qualifier::Volatile) ||
        CheckQualifier(IsLocalRestrict, Qualifier::Restrict))
      return;

    // Check for bridging the gap between the asterisk and name.
    if (Var->getLocation() == TypeSpecifier.getEnd().getLocWithOffset(1))
      TypeSpecifier.setEnd(TypeSpecifier.getEnd().getLocWithOffset(1));

    CharSourceRange FixItRange = CharSourceRange::getCharRange(TypeSpecifier);
    if (FixItRange.isInvalid())
      return;

    SourceLocation FixitLoc = FixItRange.getBegin();
    for (SourceRange &Range : RemoveQualifiersRange) {
      if (Range.getBegin() < FixitLoc)
        FixitLoc = Range.getBegin();
    }

    std::string ReplStr = [&] {
      llvm::StringRef PtrConst = isPointerConst(Var->getType()) ? "const " : "";
      llvm::StringRef LocalConst = IsLocalConst ? "const " : "";
      llvm::StringRef LocalVol = IsLocalVolatile ? "volatile " : "";
      llvm::StringRef LocalRestrict = IsLocalRestrict ? "__restrict " : "";
      return (PtrConst + "auto *" + LocalConst + LocalVol + LocalRestrict)
          .str();
    }();

    DiagnosticBuilder Diag =
        diag(FixitLoc,
             "'%select{|const }0%select{|volatile }1%select{|__restrict }2auto "
             "%3' can be declared as '%4%3'")
        << IsLocalConst << IsLocalVolatile << IsLocalRestrict << Var->getName()
        << ReplStr;

    for (SourceRange &Range : RemoveQualifiersRange) {
      Diag << FixItHint::CreateRemoval(CharSourceRange::getCharRange(Range));
    }

    Diag << FixItHint::CreateReplacement(FixItRange, ReplStr);
    return;
  }
  if (const auto *Var = Result.Nodes.getNodeAs<VarDecl>("auto_ptr")) {
    if (!isPointerConst(Var->getType()))
      return; // Pointer isn't const, no need to add const qualifier.
    if (!isAutoPointerConst(Var->getType()))
      return; // Const isn't wrapped in the auto type, so must be declared
              // explicitly.

    if (Var->getType().isLocalConstQualified()) {
      std::optional<Token> Token = findQualToken(Var, Qualifier::Const, Result);
      if (!Token || Token->getLocation().isMacroID())
        return;
    }
    if (Var->getType().isLocalVolatileQualified()) {
      std::optional<Token> Token =
          findQualToken(Var, Qualifier::Volatile, Result);
      if (!Token || Token->getLocation().isMacroID())
        return;
    }
    if (Var->getType().isLocalRestrictQualified()) {
      std::optional<Token> Token =
          findQualToken(Var, Qualifier::Restrict, Result);
      if (!Token || Token->getLocation().isMacroID())
        return;
    }

    if (std::optional<SourceRange> TypeSpec =
            getTypeSpecifierLocation(Var, Result)) {
      if (TypeSpec->isInvalid() || TypeSpec->getBegin().isMacroID() ||
          TypeSpec->getEnd().isMacroID())
        return;
      SourceLocation InsertPos = TypeSpec->getBegin();
      diag(InsertPos,
           "'auto *%select{|const }0%select{|volatile }1%2' can be declared as "
           "'const auto *%select{|const }0%select{|volatile }1%2'")
          << Var->getType().isLocalConstQualified()
          << Var->getType().isLocalVolatileQualified() << Var->getName()
          << FixItHint::CreateInsertion(InsertPos, "const ");
    }
    return;
  }
  if (const auto *Var = Result.Nodes.getNodeAs<VarDecl>("auto_ref")) {
    if (!isPointerConst(Var->getType()))
      return; // Pointer isn't const, no need to add const qualifier.
    if (!isAutoPointerConst(Var->getType()))
      // Const isn't wrapped in the auto type, so must be declared explicitly.
      return;

    if (std::optional<SourceRange> TypeSpec =
            getTypeSpecifierLocation(Var, Result)) {
      if (TypeSpec->isInvalid() || TypeSpec->getBegin().isMacroID() ||
          TypeSpec->getEnd().isMacroID())
        return;
      SourceLocation InsertPos = TypeSpec->getBegin();
      diag(InsertPos, "'auto &%0' can be declared as 'const auto &%0'")
          << Var->getName() << FixItHint::CreateInsertion(InsertPos, "const ");
    }
    return;
  }
}

} // namespace clang::tidy::readability
