//===- unittests/StaticAnalyzer/RegisterCustomCheckersTest.cpp ------------===//
//
// 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 "clang/Analysis/PathDiagnostic.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
#include "clang/StaticAnalyzer/Core/Checker.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
#include "clang/StaticAnalyzer/Frontend/AnalysisConsumer.h"
#include "clang/StaticAnalyzer/Frontend/CheckerRegistry.h"
#include "clang/Tooling/Tooling.h"
#include "gtest/gtest.h"

namespace clang {
namespace ento {

class OnlyWarningsDiagConsumer : public PathDiagnosticConsumer {
  llvm::raw_ostream &Output;

public:
  OnlyWarningsDiagConsumer(llvm::raw_ostream &Output) : Output(Output) {}
  void FlushDiagnosticsImpl(std::vector<const PathDiagnostic *> &Diags,
                            FilesMade *filesMade) override {
    for (const auto *PD : Diags) {
      Output << PD->getCheckerName() << ": ";
      Output << PD->getShortDescription() << '\n';
    }
  }

  StringRef getName() const override { return "Test"; }
};

class PathDiagConsumer : public PathDiagnosticConsumer {
  llvm::raw_ostream &Output;

public:
  PathDiagConsumer(llvm::raw_ostream &Output) : Output(Output) {}
  void FlushDiagnosticsImpl(std::vector<const PathDiagnostic *> &Diags,
                            FilesMade *filesMade) override {
    for (const auto *PD : Diags) {
      Output << PD->getCheckerName() << ": ";

      for (PathDiagnosticPieceRef Piece :
           PD->path.flatten(/*ShouldFlattenMacros*/ true)) {
        if (Piece->getKind() != PathDiagnosticPiece::Event)
          continue;
        if (Piece->getString().empty())
          continue;
        // The last event is usually the same as the warning message, skip.
        if (Piece->getString() == PD->getShortDescription())
          continue;

        Output << Piece->getString() << " | ";
      }
      Output << PD->getShortDescription() << '\n';
    }
  }

  StringRef getName() const override { return "Test"; }
};

using AddCheckerFn = void(AnalysisASTConsumer &AnalysisConsumer,
                          AnalyzerOptions &AnOpts);

template <AddCheckerFn Fn1, AddCheckerFn Fn2, AddCheckerFn... Fns>
void addChecker(AnalysisASTConsumer &AnalysisConsumer,
                AnalyzerOptions &AnOpts) {
  Fn1(AnalysisConsumer, AnOpts);
  addChecker<Fn2, Fns...>(AnalysisConsumer, AnOpts);
}

template <AddCheckerFn Fn1>
void addChecker(AnalysisASTConsumer &AnalysisConsumer,
                AnalyzerOptions &AnOpts) {
  Fn1(AnalysisConsumer, AnOpts);
}

template <AddCheckerFn... Fns> class TestAction : public ASTFrontendAction {
  llvm::raw_ostream &DiagsOutput;
  bool OnlyEmitWarnings;

public:
  TestAction(llvm::raw_ostream &DiagsOutput, bool OnlyEmitWarnings)
      : DiagsOutput(DiagsOutput), OnlyEmitWarnings(OnlyEmitWarnings) {}

  std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &Compiler,
                                                 StringRef File) override {
    std::unique_ptr<AnalysisASTConsumer> AnalysisConsumer =
        CreateAnalysisConsumer(Compiler);
    if (OnlyEmitWarnings)
      AnalysisConsumer->AddDiagnosticConsumer(
          new OnlyWarningsDiagConsumer(DiagsOutput));
    else
      AnalysisConsumer->AddDiagnosticConsumer(
          new PathDiagConsumer(DiagsOutput));
    addChecker<Fns...>(*AnalysisConsumer, *Compiler.getAnalyzerOpts());
    return std::move(AnalysisConsumer);
  }
};

inline SmallString<80> getCurrentTestNameAsFileName() {
  const ::testing::TestInfo *Info =
      ::testing::UnitTest::GetInstance()->current_test_info();

  SmallString<80> FileName;
  (Twine{Info->name()} + ".cc").toVector(FileName);
  return FileName;
}

template <AddCheckerFn... Fns>
bool runCheckerOnCode(const std::string &Code, std::string &Diags,
                      bool OnlyEmitWarnings = false) {
  const SmallVectorImpl<char> &FileName = getCurrentTestNameAsFileName();
  llvm::raw_string_ostream OS(Diags);
  return tooling::runToolOnCode(
      std::make_unique<TestAction<Fns...>>(OS, OnlyEmitWarnings), Code,
      FileName);
}

template <AddCheckerFn... Fns> bool runCheckerOnCode(const std::string &Code) {
  std::string Diags;
  return runCheckerOnCode<Fns...>(Code, Diags);
}

template <AddCheckerFn... Fns>
bool runCheckerOnCodeWithArgs(const std::string &Code,
                              const std::vector<std::string> &Args,
                              std::string &Diags,
                              bool OnlyEmitWarnings = false) {
  const SmallVectorImpl<char> &FileName = getCurrentTestNameAsFileName();
  llvm::raw_string_ostream OS(Diags);
  return tooling::runToolOnCodeWithArgs(
      std::make_unique<TestAction<Fns...>>(OS, OnlyEmitWarnings), Code, Args,
      FileName);
}

template <AddCheckerFn... Fns>
bool runCheckerOnCodeWithArgs(const std::string &Code,
                              const std::vector<std::string> &Args) {
  std::string Diags;
  return runCheckerOnCodeWithArgs<Fns...>(Code, Args, Diags);
}

} // namespace ento
} // namespace clang
