//===--- StringFindStartswithCheck.cc - clang-tidy---------------*- C++ -*-===//
//
// 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 "StringFindStartswithCheck.h"

#include "../utils/OptionsUtils.h"
#include "clang/AST/ASTContext.h"
#include "clang/ASTMatchers/ASTMatchers.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Lex/Lexer.h"
#include "clang/Lex/Preprocessor.h"

using namespace clang::ast_matchers;

namespace clang::tidy::abseil {

const auto DefaultStringLikeClasses =
    "::std::basic_string;::std::basic_string_view";

StringFindStartswithCheck::StringFindStartswithCheck(StringRef Name,
                                                     ClangTidyContext *Context)
    : ClangTidyCheck(Name, Context),
      StringLikeClasses(utils::options::parseStringList(
          Options.get("StringLikeClasses", DefaultStringLikeClasses))),
      IncludeInserter(Options.getLocalOrGlobal("IncludeStyle",
                                               utils::IncludeSorter::IS_LLVM),
                      areDiagsSelfContained()),
      AbseilStringsMatchHeader(
          Options.get("AbseilStringsMatchHeader", "absl/strings/match.h")) {}

void StringFindStartswithCheck::registerMatchers(MatchFinder *Finder) {
  auto ZeroLiteral = integerLiteral(equals(0));
  auto StringClassMatcher = cxxRecordDecl(hasAnyName(StringLikeClasses));
  auto StringType = hasUnqualifiedDesugaredType(
      recordType(hasDeclaration(StringClassMatcher)));

  auto StringFind = cxxMemberCallExpr(
      // .find()-call on a string...
      callee(cxxMethodDecl(hasName("find")).bind("findfun")),
      on(hasType(StringType)),
      // ... with some search expression ...
      hasArgument(0, expr().bind("needle")),
      // ... and either "0" as second argument or the default argument (also 0).
      anyOf(hasArgument(1, ZeroLiteral), hasArgument(1, cxxDefaultArgExpr())));

  Finder->addMatcher(
      // Match [=!]= with a zero on one side and a string.find on the other.
      binaryOperator(
          hasAnyOperatorName("==", "!="),
          hasOperands(ignoringParenImpCasts(ZeroLiteral),
                      ignoringParenImpCasts(StringFind.bind("findexpr"))))
          .bind("expr"),
      this);

  auto StringRFind = cxxMemberCallExpr(
      // .rfind()-call on a string...
      callee(cxxMethodDecl(hasName("rfind")).bind("findfun")),
      on(hasType(StringType)),
      // ... with some search expression ...
      hasArgument(0, expr().bind("needle")),
      // ... and "0" as second argument.
      hasArgument(1, ZeroLiteral));

  Finder->addMatcher(
      // Match [=!]= with either a zero or npos on one side and a string.rfind
      // on the other.
      binaryOperator(
          hasAnyOperatorName("==", "!="),
          hasOperands(ignoringParenImpCasts(ZeroLiteral),
                      ignoringParenImpCasts(StringRFind.bind("findexpr"))))
          .bind("expr"),
      this);
}

void StringFindStartswithCheck::check(const MatchFinder::MatchResult &Result) {
  const ASTContext &Context = *Result.Context;
  const SourceManager &Source = Context.getSourceManager();

  // Extract matching (sub)expressions
  const auto *ComparisonExpr = Result.Nodes.getNodeAs<BinaryOperator>("expr");
  assert(ComparisonExpr != nullptr);
  const auto *Needle = Result.Nodes.getNodeAs<Expr>("needle");
  assert(Needle != nullptr);
  const Expr *Haystack = Result.Nodes.getNodeAs<CXXMemberCallExpr>("findexpr")
                             ->getImplicitObjectArgument();
  assert(Haystack != nullptr);
  const auto *FindFun = Result.Nodes.getNodeAs<CXXMethodDecl>("findfun");
  assert(FindFun != nullptr);

  bool Rev = FindFun->getName().contains("rfind");

  if (ComparisonExpr->getBeginLoc().isMacroID())
    return;

  // Get the source code blocks (as characters) for both the string object
  // and the search expression
  const StringRef NeedleExprCode = Lexer::getSourceText(
      CharSourceRange::getTokenRange(Needle->getSourceRange()), Source,
      Context.getLangOpts());
  const StringRef HaystackExprCode = Lexer::getSourceText(
      CharSourceRange::getTokenRange(Haystack->getSourceRange()), Source,
      Context.getLangOpts());

  // Create the StartsWith string, negating if comparison was "!=".
  bool Neg = ComparisonExpr->getOpcode() == BO_NE;

  // Create the warning message and a FixIt hint replacing the original expr.
  auto Diagnostic =
      diag(ComparisonExpr->getBeginLoc(),
           "use %select{absl::StartsWith|!absl::StartsWith}0 "
           "instead of %select{find()|rfind()}1 %select{==|!=}0 0")
      << Neg << Rev;

  Diagnostic << FixItHint::CreateReplacement(
      ComparisonExpr->getSourceRange(),
      ((Neg ? "!absl::StartsWith(" : "absl::StartsWith(") + HaystackExprCode +
       ", " + NeedleExprCode + ")")
          .str());

  // Create a preprocessor #include FixIt hint (createIncludeInsertion checks
  // whether this already exists).
  Diagnostic << IncludeInserter.createIncludeInsertion(
      Source.getFileID(ComparisonExpr->getBeginLoc()),
      AbseilStringsMatchHeader);
}

void StringFindStartswithCheck::registerPPCallbacks(
    const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) {
  IncludeInserter.registerPreprocessor(PP);
}

void StringFindStartswithCheck::storeOptions(
    ClangTidyOptions::OptionMap &Opts) {
  Options.store(Opts, "StringLikeClasses",
                utils::options::serializeStringList(StringLikeClasses));
  Options.store(Opts, "IncludeStyle", IncludeInserter.getStyle());
  Options.store(Opts, "AbseilStringsMatchHeader", AbseilStringsMatchHeader);
}

} // namespace clang::tidy::abseil
