//===--- UseAnyOfAllOfCheck.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 "UseAnyOfAllOfCheck.h"
#include "clang/AST/ASTContext.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/Analysis/Analyses/ExprMutationAnalyzer.h"
#include "clang/Frontend/CompilerInstance.h"

using namespace clang::ast_matchers;

namespace clang {
namespace {
/// Matches a Stmt whose parent is a CompoundStmt, and which is directly
/// followed by a Stmt matching the inner matcher.
AST_MATCHER_P(Stmt, nextStmt, ast_matchers::internal::Matcher<Stmt>,
              InnerMatcher) {
  DynTypedNodeList Parents = Finder->getASTContext().getParents(Node);
  if (Parents.size() != 1)
    return false;

  auto *C = Parents[0].get<CompoundStmt>();
  if (!C)
    return false;

  const auto *I = llvm::find(C->body(), &Node);
  assert(I != C->body_end() && "C is parent of Node");
  if (++I == C->body_end())
    return false; // Node is last statement.

  return InnerMatcher.matches(**I, Finder, Builder);
}
} // namespace

namespace tidy::readability {

void UseAnyOfAllOfCheck::registerMatchers(MatchFinder *Finder) {
  auto Returns = [](bool V) {
    return returnStmt(hasReturnValue(cxxBoolLiteral(equals(V))));
  };

  auto ReturnsButNotTrue =
      returnStmt(hasReturnValue(unless(cxxBoolLiteral(equals(true)))));
  auto ReturnsButNotFalse =
      returnStmt(hasReturnValue(unless(cxxBoolLiteral(equals(false)))));

  Finder->addMatcher(
      cxxForRangeStmt(
          nextStmt(Returns(false).bind("final_return")),
          hasBody(allOf(hasDescendant(Returns(true)),
                        unless(anyOf(hasDescendant(breakStmt()),
                                     hasDescendant(gotoStmt()),
                                     hasDescendant(ReturnsButNotTrue))))))
          .bind("any_of_loop"),
      this);

  Finder->addMatcher(
      cxxForRangeStmt(
          nextStmt(Returns(true).bind("final_return")),
          hasBody(allOf(hasDescendant(Returns(false)),
                        unless(anyOf(hasDescendant(breakStmt()),
                                     hasDescendant(gotoStmt()),
                                     hasDescendant(ReturnsButNotFalse))))))
          .bind("all_of_loop"),
      this);
}

static bool isViableLoop(const CXXForRangeStmt &S, ASTContext &Context) {

  ExprMutationAnalyzer Mutations(*S.getBody(), Context);
  if (Mutations.isMutated(S.getLoopVariable()))
    return false;
  const auto Matches =
      match(findAll(declRefExpr().bind("decl_ref")), *S.getBody(), Context);

  return llvm::none_of(Matches, [&Mutations](auto &DeclRef) {
    // TODO: allow modifications of loop-local variables
    return Mutations.isMutated(
        DeclRef.template getNodeAs<DeclRefExpr>("decl_ref")->getDecl());
  });
}

void UseAnyOfAllOfCheck::check(const MatchFinder::MatchResult &Result) {

  if (const auto *S = Result.Nodes.getNodeAs<CXXForRangeStmt>("any_of_loop")) {
    if (!isViableLoop(*S, *Result.Context))
      return;

    diag(S->getForLoc(), "replace loop by 'std%select{|::ranges}0::any_of()'")
        << getLangOpts().CPlusPlus20;
  } else if (const auto *S =
                 Result.Nodes.getNodeAs<CXXForRangeStmt>("all_of_loop")) {
    if (!isViableLoop(*S, *Result.Context))
      return;

    diag(S->getForLoc(), "replace loop by 'std%select{|::ranges}0::all_of()'")
        << getLangOpts().CPlusPlus20;
  }
}

} // namespace tidy::readability
} // namespace clang
