//===--- ReplaceRandomShuffleCheck.cpp - clang-tidy------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "ReplaceRandomShuffleCheck.h"
#include "../utils/FixItHintUtils.h"
#include "clang/AST/ASTContext.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Tooling/FixIt.h"

using namespace clang::ast_matchers;

namespace clang {
namespace tidy {
namespace modernize {

ReplaceRandomShuffleCheck::ReplaceRandomShuffleCheck(StringRef Name,
                                                     ClangTidyContext *Context)
    : ClangTidyCheck(Name, Context),
      IncludeStyle(utils::IncludeSorter::parseIncludeStyle(
          Options.get("IncludeStyle", "llvm"))) {}

void ReplaceRandomShuffleCheck::registerMatchers(MatchFinder *Finder) {
  if (!getLangOpts().CPlusPlus11)
    return;

  const auto Begin = hasArgument(0, expr());
  const auto End = hasArgument(1, expr());
  const auto RandomFunc = hasArgument(2, expr().bind("randomFunc"));
  Finder->addMatcher(
      callExpr(anyOf(allOf(Begin, End, argumentCountIs(2)),
                     allOf(Begin, End, RandomFunc, argumentCountIs(3))),
               hasDeclaration(functionDecl(hasName("::std::random_shuffle"))),
               has(implicitCastExpr(has(declRefExpr().bind("name")))))
          .bind("match"),
      this);
}

void ReplaceRandomShuffleCheck::registerPPCallbacks(
    CompilerInstance &Compiler) {
  IncludeInserter = llvm::make_unique<utils::IncludeInserter>(
      Compiler.getSourceManager(), Compiler.getLangOpts(), IncludeStyle);
  Compiler.getPreprocessor().addPPCallbacks(
      IncludeInserter->CreatePPCallbacks());
}

void ReplaceRandomShuffleCheck::storeOptions(
    ClangTidyOptions::OptionMap &Opts) {
  Options.store(Opts, "IncludeStyle",
                utils::IncludeSorter::toString(IncludeStyle));
}

void ReplaceRandomShuffleCheck::check(const MatchFinder::MatchResult &Result) {
  const auto *MatchedDecl = Result.Nodes.getNodeAs<DeclRefExpr>("name");
  const auto *MatchedArgumentThree = Result.Nodes.getNodeAs<Expr>("randomFunc");
  const auto *MatchedCallExpr = Result.Nodes.getNodeAs<CallExpr>("match");

  if (MatchedCallExpr->getLocStart().isMacroID())
    return;

  auto Diag = [&] {
    if (MatchedCallExpr->getNumArgs() == 3) {
      auto DiagL =
          diag(MatchedCallExpr->getLocStart(),
               "'std::random_shuffle' has been removed in C++17; use "
               "'std::shuffle' and an alternative random mechanism instead");
      DiagL << FixItHint::CreateReplacement(
          MatchedArgumentThree->getSourceRange(),
          "std::mt19937(std::random_device()())");
      return DiagL;
    } else {
      auto DiagL = diag(MatchedCallExpr->getLocStart(),
                        "'std::random_shuffle' has been removed in C++17; use "
                        "'std::shuffle' instead");
      DiagL << FixItHint::CreateInsertion(
          MatchedCallExpr->getRParenLoc(),
          ", std::mt19937(std::random_device()())");
      return DiagL;
    }
  }();

  std::string NewName = "shuffle";
  StringRef ContainerText = Lexer::getSourceText(
      CharSourceRange::getTokenRange(MatchedDecl->getSourceRange()),
      *Result.SourceManager, getLangOpts());
  if (ContainerText.startswith("std::"))
    NewName = "std::" + NewName;

  Diag << FixItHint::CreateRemoval(MatchedDecl->getSourceRange());
  Diag << FixItHint::CreateInsertion(MatchedDecl->getLocStart(), NewName);

  if (Optional<FixItHint> IncludeFixit =
          IncludeInserter->CreateIncludeInsertion(
              Result.Context->getSourceManager().getFileID(
                  MatchedCallExpr->getLocStart()),
              "random", /*IsAngled=*/true))
    Diag << IncludeFixit.getValue();
}

} // namespace modernize
} // namespace tidy
} // namespace clang
