// 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/inference/replace_macros.h"

#include <memory>
#include <string>
#include <string_view>

#include "nullability/inference/ctn_replacement_macros.h"
#include "nullability/macro_arg_capture.h"
#include "clang/AST/Decl.h"
#include "clang/AST/Expr.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/ASTMatchers/ASTMatchers.h"
#include "clang/Testing/TestAST.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h"
#include "external/llvm-project/third-party/unittest/googlemock/include/gmock/gmock.h"  // IWYU pragma: keep
#include "external/llvm-project/third-party/unittest/googletest/include/gtest/gtest.h"

namespace clang::tidy::nullability {
namespace {

using ::clang::CallExpr;
using ::clang::ast_matchers::anyOf;
using ::clang::ast_matchers::callExpr;
using ::clang::ast_matchers::functionDecl;
using ::clang::ast_matchers::hasDeclaration;
using ::clang::ast_matchers::hasName;
using ::clang::ast_matchers::match;
using ::clang::ast_matchers::selectFirst;
using ::testing::IsEmpty;
using ::testing::IsNull;
using ::testing::NotNull;

clang::TestInputs getInputs(llvm::StringRef Source) {
  clang::TestInputs Inputs = Source;
  for (const auto& Entry : llvm::ArrayRef(ctn_replacement_macros_create(),
                                          ctn_replacement_macros_size()))
    Inputs.ExtraFiles.try_emplace(Entry.name, Entry.data);
  Inputs.ExtraArgs.push_back("-include");
  Inputs.ExtraArgs.push_back(std::string(ReplacementMacrosHeaderFileName));

  Inputs.MakeAction = []() { return std::make_unique<ReplaceMacrosAction>(); };
  return Inputs;
}

TEST(ReplaceMacrosAction, ReplacesCHECK) {
  static constexpr std::string_view Source = R"cc(
#define CHECK(x) \
      if (!x) __builtin_abort();

    void foo() { CHECK(nullptr); }
  )cc";
  clang::TestAST AST(getInputs(Source));

  const CallExpr* ArgumentCapture = selectFirst<CallExpr>(
      "call", match(callExpr(hasDeclaration(
                                 functionDecl(hasName(ArgCaptureAbortIfFalse))))
                        .bind("call"),
                    AST.context()));
  ASSERT_THAT(ArgumentCapture, NotNull());
  ASSERT_THAT(ArgumentCapture->getArg(0), NotNull());
  EXPECT_TRUE(ArgumentCapture->getArg(0)->isNullPointerConstant(
      AST.context(), Expr::NPC_ValueDependentIsNotNull));
}

TEST(ReplaceMacrosAction, ReplacesCHECK_NE) {
  static constexpr std::string_view Source = R"cc(
#define CHECK_NE(x, y) \
      if (x == y) __builtin_abort();

    void foo() {
      CHECK_NE(nullptr, nullptr);
    }
  )cc";
  clang::TestAST AST(getInputs(Source));

  const CallExpr* ArgumentCapture = selectFirst<CallExpr>(
      "call", match(callExpr(hasDeclaration(
                                 functionDecl(hasName(ArgCaptureAbortIfEqual))))
                        .bind("call"),
                    AST.context()));
  ASSERT_THAT(ArgumentCapture, NotNull());
  ASSERT_THAT(ArgumentCapture->getArg(0), NotNull());
  EXPECT_TRUE(ArgumentCapture->getArg(0)->isNullPointerConstant(
      AST.context(), Expr::NPC_ValueDependentIsNotNull));
  ASSERT_THAT(ArgumentCapture->getArg(1), NotNull());
  EXPECT_TRUE(ArgumentCapture->getArg(1)->isNullPointerConstant(
      AST.context(), Expr::NPC_ValueDependentIsNotNull));
}

TEST(ReplaceMacrosAction, DoesNotReplaceMacroNotInReplacementFile) {
  static constexpr std::string_view Source = R"cc(
#define TOTALLY_MADE_UP_CHECK_THAT_IS_NOT_IN_REPLACEMENT_FILE(x) \
      if (!x) __builtin_abort();

    void foo() {
      TOTALLY_MADE_UP_CHECK_THAT_IS_NOT_IN_REPLACEMENT_FILE(nullptr);
    }
  )cc";
  clang::TestAST AST(getInputs(Source));

  const CallExpr* ArgumentCaptureFunctionCall = selectFirst<CallExpr>(
      "call",
      match(callExpr(hasDeclaration(
                         anyOf(functionDecl(hasName(ArgCaptureAbortIfFalse)),
                               functionDecl(hasName(ArgCaptureAbortIfEqual)))))
                .bind("call"),
            AST.context()));
  ASSERT_THAT(ArgumentCaptureFunctionCall, IsNull());
}

TEST(ReplaceMacrosAction, ArgumentCaptureCompilesWithVariousTypes) {
  static constexpr std::string_view Source = R"cc(
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wmacro-redefined"
#define CHECK(x) \
      if (!x) __builtin_abort();
#pragma clang diagnostic pop

    struct S {
      S();
      S(const S &);
      S(S &&);

      operator bool() &;
      operator bool() const &;
    };

    void foo() {
      S s;
      CHECK(static_cast<S *>(&s));
      CHECK(static_cast<const S *>(&s));
      CHECK(static_cast<S &>(s));
      CHECK(static_cast<const S &>(s));
      CHECK(static_cast<S &&>(s));
    }
  )cc";

  clang::TestAST AST(getInputs(Source));

  EXPECT_THAT(AST.diagnostics(), IsEmpty());
}
}  // namespace
}  // namespace clang::tidy::nullability
