// Part of the Crubit project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#include "nullability/test/check_diagnostics.h"

#include <algorithm>
#include <iterator>
#include <memory>
#include <vector>

#include "nullability/pointer_nullability_diagnosis.h"
#include "nullability/pragma.h"
#include "nullability/test/test_headers.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/Decl.h"
#include "clang/ASTMatchers/ASTMatchers.h"
#include "clang/Analysis/CFG.h"
#include "clang/Frontend/FrontendActions.h"
#include "clang/Testing/CommandLineArgs.h"
#include "clang/Testing/TestAST.h"
#include "clang/Tooling/Tooling.h"
#include "third_party/llvm/llvm-project/clang/unittests/Analysis/FlowSensitive/TestingSupport.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/raw_ostream.h"
#include "third_party/llvm/llvm-project/third-party/unittest/googlemock/include/gmock/gmock.h"
#include "third_party/llvm/llvm-project/third-party/unittest/googletest/include/gtest/gtest.h"

namespace clang::tidy::nullability {

static bool checkDiagnostics(llvm::StringRef SourceCode, TestLanguage Lang) {
  using ast_matchers::BoundNodes;
  using ast_matchers::hasName;
  using ast_matchers::match;
  using ast_matchers::stmt;
  using ast_matchers::valueDecl;

  llvm::Annotations AnnotatedCode(SourceCode);
  clang::TestInputs Inputs(AnnotatedCode.code());
  Inputs.Language = Lang;
  Inputs.ExtraArgs = {
      "-fsyntax-only",
      "-Wno-unused-value",
      "-Wno-nonnull",
      "-include",
      "check_diagnostics_preamble.h",
      "-I.",
  };
  for (const auto &Entry :
       llvm::ArrayRef(test_headers_create(), test_headers_size()))
    Inputs.ExtraFiles.try_emplace(Entry.name, Entry.data);
  NullabilityPragmas Pragmas;
  Inputs.MakeAction = [&] {
    struct Action : public SyntaxOnlyAction {
      NullabilityPragmas &Pragmas;
      Action(NullabilityPragmas &Pragmas) : Pragmas(Pragmas) {}

      std::unique_ptr<ASTConsumer> CreateASTConsumer(
          CompilerInstance &CI, llvm::StringRef File) override {
        registerPragmaHandler(CI.getPreprocessor(), Pragmas);
        return SyntaxOnlyAction::CreateASTConsumer(CI, File);
      }
    };
    return std::make_unique<Action>(Pragmas);
  };
  clang::TestAST AST(Inputs);

  SmallVector<BoundNodes, 1> MatchResult =
      match(valueDecl(hasName("target")).bind("target"), AST.context());
  if (MatchResult.empty()) {
    ADD_FAILURE() << "didn't find target declaration";
    return false;
  }

  bool Success = true;
  for (const ast_matchers::BoundNodes &BN : MatchResult) {
    const auto *Target = BN.getNodeAs<ValueDecl>("target");

    llvm::DenseMap<unsigned, std::string> Annotations =
        dataflow::test::buildLineToAnnotationMapping(
            AST.sourceManager(), AST.context().getLangOpts(),
            Target->getSourceRange(), AnnotatedCode);

    llvm::SmallVector<PointerNullabilityDiagnostic> Diagnostics;
    if (llvm::Error Err =
            diagnosePointerNullability(Target, Pragmas).moveInto(Diagnostics)) {
      ADD_FAILURE() << Err;
      return false;
    }

    // Note: use sorted sets for expected and actual lines to improve
    // readability of the error output in case the test fails.
    std::set<unsigned> ExpectedLines, ActualLines;
    for (const auto &[Line, _] : Annotations) {
      ExpectedLines.insert(Line);
    }
    for (const auto &Diag : Diagnostics)
      ActualLines.insert(
          AST.sourceManager().getPresumedLineNumber(Diag.Range.getBegin()));
    if (ActualLines != ExpectedLines) {
      Success = false;

      // Clang's line numbers are one-based, so add an extra empty line at the
      // beginning.
      llvm::SmallVector<llvm::StringRef> Lines = {""};
      SourceCode.split(Lines, '\n');

      std::vector<unsigned> ExpectedButNotFound;
      std::set_difference(ExpectedLines.begin(), ExpectedLines.end(),
                          ActualLines.begin(), ActualLines.end(),
                          std::back_inserter(ExpectedButNotFound));
      std::vector<unsigned> FoundButNotExpected;
      std::set_difference(ActualLines.begin(), ActualLines.end(),
                          ExpectedLines.begin(), ExpectedLines.end(),
                          std::back_inserter(FoundButNotExpected));

      std::string ErrorMessage;
      llvm::raw_string_ostream OS(ErrorMessage);

      if (!ExpectedButNotFound.empty()) {
        OS << "Expected diagnostics but didn't find them:\n";
        for (unsigned Line : ExpectedButNotFound)
          OS << Line << ": " << Lines[Line] << "\n";
      }
      if (!FoundButNotExpected.empty()) {
        OS << "Found diagnostics but didn't expect them:\n";
        for (unsigned Line : FoundButNotExpected)
          OS << Line << ": " << Lines[Line] << "\n";
      }

      ADD_FAILURE() << ErrorMessage;
    }
  }

  return Success;
}

bool checkDiagnostics(llvm::StringRef SourceCode) {
  // Run in C++17 and C++20 mode to cover differences in the AST between modes
  // (e.g. C++20 can contain `CXXRewrittenBinaryOperator`).
  for (TestLanguage Lang : {TestLanguage::Lang_CXX17, TestLanguage::Lang_CXX20})
    if (!checkDiagnostics(SourceCode, Lang)) return false;
  return true;
}

}  // namespace clang::tidy::nullability
