//===--- ReplaceRandomShuffleCheck.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 "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.getLocalOrGlobal("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(
    const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) {
  IncludeInserter = std::make_unique<utils::IncludeInserter>(SM, getLangOpts(),
                                                              IncludeStyle);
  PP->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->getBeginLoc().isMacroID())
    return;

  auto Diag = [&] {
    if (MatchedCallExpr->getNumArgs() == 3) {
      auto DiagL =
          diag(MatchedCallExpr->getBeginLoc(),
               "'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->getBeginLoc(),
                        "'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->getBeginLoc(), NewName);

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

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