//===--- PreambleTests.cpp --------------------------------------*- C++ -*-===//
//
// 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 "Annotations.h"
#include "Compiler.h"
#include "Headers.h"
#include "Hover.h"
#include "Preamble.h"
#include "SourceCode.h"
#include "TestFS.h"
#include "TestTU.h"
#include "XRefs.h"
#include "clang/Format/Format.h"
#include "clang/Frontend/PrecompiledPreamble.h"
#include "clang/Lex/PreprocessorOptions.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/VirtualFileSystem.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include <clang/Frontend/FrontendActions.h>
#include <memory>
#include <string>
#include <vector>

using testing::Contains;
using testing::Field;
using testing::Matcher;
using testing::MatchesRegex;

namespace clang {
namespace clangd {
namespace {

MATCHER_P2(Distance, File, D, "") {
  return arg.first() == File && arg.second == D;
}

// Builds a preamble for BaselineContents, patches it for ModifiedContents and
// returns the includes in the patch.
IncludeStructure
collectPatchedIncludes(llvm::StringRef ModifiedContents,
                       llvm::StringRef BaselineContents,
                       llvm::StringRef MainFileName = "main.cpp") {
  MockFS FS;
  auto TU = TestTU::withCode(BaselineContents);
  TU.Filename = MainFileName.str();
  // ms-compatibility changes meaning of #import, make sure it is turned off.
  TU.ExtraArgs = {"-fno-ms-compatibility"};
  auto BaselinePreamble = TU.preamble();
  // Create the patch.
  TU.Code = ModifiedContents.str();
  auto PI = TU.inputs(FS);
  auto PP = PreamblePatch::create(testPath(TU.Filename), PI, *BaselinePreamble);
  // Collect patch contents.
  IgnoreDiagnostics Diags;
  auto CI = buildCompilerInvocation(PI, Diags);
  PP.apply(*CI);
  // Run preprocessor over the modified contents with patched Invocation. We
  // provide a preamble and trim contents to ensure only the implicit header
  // introduced by the patch is parsed and nothing else.
  // We don't run PP directly over the patch cotents to test production
  // behaviour.
  auto Bounds = Lexer::ComputePreamble(ModifiedContents, *CI->getLangOpts());
  auto Clang =
      prepareCompilerInstance(std::move(CI), &BaselinePreamble->Preamble,
                              llvm::MemoryBuffer::getMemBufferCopy(
                                  ModifiedContents.slice(0, Bounds.Size).str()),
                              PI.TFS->view(PI.CompileCommand.Directory), Diags);
  PreprocessOnlyAction Action;
  if (!Action.BeginSourceFile(*Clang, Clang->getFrontendOpts().Inputs[0])) {
    ADD_FAILURE() << "failed begin source file";
    return {};
  }
  IncludeStructure Includes;
  Clang->getPreprocessor().addPPCallbacks(
      collectIncludeStructureCallback(Clang->getSourceManager(), &Includes));
  if (llvm::Error Err = Action.Execute()) {
    ADD_FAILURE() << "failed to execute action: " << std::move(Err);
    return {};
  }
  Action.EndSourceFile();
  return Includes;
}

// Check preamble lexing logic by building an empty preamble and patching it
// with all the contents.
TEST(PreamblePatchTest, IncludeParsing) {
  // We expect any line with a point to show up in the patch.
  llvm::StringRef Cases[] = {
      // Only preamble
      R"cpp(^#include "a.h")cpp",
      // Both preamble and mainfile
      R"cpp(
        ^#include "a.h"
        garbage, finishes preamble
        #include "a.h")cpp",
      // Mixed directives
      R"cpp(
        ^#include "a.h"
        #pragma directive
        // some comments
        ^#include_next <a.h>
        #ifdef skipped
        ^#import "a.h"
        #endif)cpp",
      // Broken directives
      R"cpp(
        #include "a
        ^#include "a.h"
        #include <b
        ^#include <b.h>)cpp",
      // Directive is not part of preamble if it is not the token immediately
      // followed by the hash (#).
      R"cpp(
        ^#include "a.h"
        #/**/include <b.h>)cpp",
  };

  for (const auto &Case : Cases) {
    Annotations Test(Case);
    const auto Code = Test.code();
    SCOPED_TRACE(Code);

    auto Includes =
        collectPatchedIncludes(Code, /*BaselineContents=*/"").MainFileIncludes;
    auto Points = Test.points();
    ASSERT_EQ(Includes.size(), Points.size());
    for (size_t I = 0, E = Includes.size(); I != E; ++I)
      EXPECT_EQ(Includes[I].HashLine, Points[I].line);
  }
}

TEST(PreamblePatchTest, ContainsNewIncludes) {
  constexpr llvm::StringLiteral BaselineContents = R"cpp(
    #include <a.h>
    #include <b.h> // This will be removed
    #include <c.h>
  )cpp";
  constexpr llvm::StringLiteral ModifiedContents = R"cpp(
    #include <a.h>
    #include <c.h> // This has changed a line.
    #include <c.h> // This is a duplicate.
    #include <d.h> // This is newly introduced.
  )cpp";
  auto Includes = collectPatchedIncludes(ModifiedContents, BaselineContents)
                      .MainFileIncludes;
  EXPECT_THAT(Includes, ElementsAre(AllOf(Field(&Inclusion::Written, "<d.h>"),
                                          Field(&Inclusion::HashLine, 4))));
}

TEST(PreamblePatchTest, MainFileIsEscaped) {
  auto Includes = collectPatchedIncludes("#include <a.h>", "", "file\"name.cpp")
                      .MainFileIncludes;
  EXPECT_THAT(Includes, ElementsAre(AllOf(Field(&Inclusion::Written, "<a.h>"),
                                          Field(&Inclusion::HashLine, 0))));
}

TEST(PreamblePatchTest, PatchesPreambleIncludes) {
  MockFS FS;
  IgnoreDiagnostics Diags;
  auto TU = TestTU::withCode(R"cpp(
    #include "a.h"
    #include "c.h"
  )cpp");
  TU.AdditionalFiles["a.h"] = "#include \"b.h\"";
  TU.AdditionalFiles["b.h"] = "";
  TU.AdditionalFiles["c.h"] = "";
  auto PI = TU.inputs(FS);
  auto BaselinePreamble = buildPreamble(
      TU.Filename, *buildCompilerInvocation(PI, Diags), PI, true, nullptr);
  // We drop c.h from modified and add a new header. Since the latter is patched
  // we should only get a.h in preamble includes.
  TU.Code = R"cpp(
    #include "a.h"
    #include "b.h"
  )cpp";
  auto PP = PreamblePatch::create(testPath(TU.Filename), TU.inputs(FS),
                                  *BaselinePreamble);
  // Only a.h should exists in the preamble, as c.h has been dropped and b.h was
  // newly introduced.
  EXPECT_THAT(PP.preambleIncludes(),
              ElementsAre(AllOf(Field(&Inclusion::Written, "\"a.h\""),
                                Field(&Inclusion::Resolved, testPath("a.h")))));
}

llvm::Optional<ParsedAST> createPatchedAST(llvm::StringRef Baseline,
                                           llvm::StringRef Modified) {
  auto BaselinePreamble = TestTU::withCode(Baseline).preamble();
  if (!BaselinePreamble) {
    ADD_FAILURE() << "Failed to build baseline preamble";
    return llvm::None;
  }

  IgnoreDiagnostics Diags;
  MockFS FS;
  auto TU = TestTU::withCode(Modified);
  auto CI = buildCompilerInvocation(TU.inputs(FS), Diags);
  if (!CI) {
    ADD_FAILURE() << "Failed to build compiler invocation";
    return llvm::None;
  }
  return ParsedAST::build(testPath(TU.Filename), TU.inputs(FS), std::move(CI),
                          {}, BaselinePreamble);
}

std::string getPreamblePatch(llvm::StringRef Baseline,
                             llvm::StringRef Modified) {
  auto BaselinePreamble = TestTU::withCode(Baseline).preamble();
  if (!BaselinePreamble) {
    ADD_FAILURE() << "Failed to build baseline preamble";
    return "";
  }
  MockFS FS;
  auto TU = TestTU::withCode(Modified);
  return PreamblePatch::create(testPath("main.cpp"), TU.inputs(FS),
                               *BaselinePreamble)
      .text()
      .str();
}

TEST(PreamblePatchTest, Define) {
  // BAR should be defined while parsing the AST.
  struct {
    const char *const Contents;
    const char *const ExpectedPatch;
  } Cases[] = {
      {
          R"cpp(
        #define BAR
        [[BAR]])cpp",
          R"cpp(#line 0 ".*main.cpp"
#line 2
#define         BAR
)cpp",
      },
      // multiline macro
      {
          R"cpp(
        #define BAR \

        [[BAR]])cpp",
          R"cpp(#line 0 ".*main.cpp"
#line 2
#define         BAR
)cpp",
      },
      // multiline macro
      {
          R"cpp(
        #define \
                BAR
        [[BAR]])cpp",
          R"cpp(#line 0 ".*main.cpp"
#line 3
#define         BAR
)cpp",
      },
  };

  for (const auto &Case : Cases) {
    SCOPED_TRACE(Case.Contents);
    Annotations Modified(Case.Contents);
    EXPECT_THAT(getPreamblePatch("", Modified.code()),
                MatchesRegex(Case.ExpectedPatch));

    auto AST = createPatchedAST("", Modified.code());
    ASSERT_TRUE(AST);
    EXPECT_THAT(AST->getDiagnostics(),
                Not(Contains(Field(&Diag::Range, Modified.range()))));
  }
}

TEST(PreamblePatchTest, OrderingPreserved) {
  llvm::StringLiteral Baseline = "#define BAR(X) X";
  Annotations Modified(R"cpp(
    #define BAR(X, Y) X Y
    #define BAR(X) X
    [[BAR]](int y);
  )cpp");

  llvm::StringLiteral ExpectedPatch(R"cpp(#line 0 ".*main.cpp"
#line 2
#define     BAR\(X, Y\) X Y
#line 3
#define     BAR\(X\) X
)cpp");
  EXPECT_THAT(getPreamblePatch(Baseline, Modified.code()),
              MatchesRegex(ExpectedPatch.str()));

  auto AST = createPatchedAST(Baseline, Modified.code());
  ASSERT_TRUE(AST);
  EXPECT_THAT(AST->getDiagnostics(),
              Not(Contains(Field(&Diag::Range, Modified.range()))));
}

TEST(PreamblePatchTest, LocateMacroAtWorks) {
  struct {
    const char *const Baseline;
    const char *const Modified;
  } Cases[] = {
      // Addition of new directive
      {
          "",
          R"cpp(
            #define $def^FOO
            $use^FOO)cpp",
      },
      // Available inside preamble section
      {
          "",
          R"cpp(
            #define $def^FOO
            #undef $use^FOO)cpp",
      },
      // Available after undef, as we don't patch those
      {
          "",
          R"cpp(
            #define $def^FOO
            #undef FOO
            $use^FOO)cpp",
      },
      // Identifier on a different line
      {
          "",
          R"cpp(
            #define \
              $def^FOO
            $use^FOO)cpp",
      },
      // In presence of comment tokens
      {
          "",
          R"cpp(
            #\
              define /* FOO */\
              /* FOO */ $def^FOO
            $use^FOO)cpp",
      },
      // Moved around
      {
          "#define FOO",
          R"cpp(
            #define BAR
            #define $def^FOO
            $use^FOO)cpp",
      },
  };
  for (const auto &Case : Cases) {
    SCOPED_TRACE(Case.Modified);
    llvm::Annotations Modified(Case.Modified);
    auto AST = createPatchedAST(Case.Baseline, Modified.code());
    ASSERT_TRUE(AST);

    const auto &SM = AST->getSourceManager();
    auto *MacroTok = AST->getTokens().spelledTokenAt(
        SM.getComposedLoc(SM.getMainFileID(), Modified.point("use")));
    ASSERT_TRUE(MacroTok);

    auto FoundMacro = locateMacroAt(*MacroTok, AST->getPreprocessor());
    ASSERT_TRUE(FoundMacro);
    EXPECT_THAT(FoundMacro->Name, "FOO");

    auto MacroLoc = FoundMacro->NameLoc;
    EXPECT_EQ(SM.getFileID(MacroLoc), SM.getMainFileID());
    EXPECT_EQ(SM.getFileOffset(MacroLoc), Modified.point("def"));
  }
}

TEST(PreamblePatchTest, LocateMacroAtDeletion) {
  {
    // We don't patch deleted define directives, make sure we don't crash.
    llvm::StringLiteral Baseline = "#define FOO";
    llvm::Annotations Modified("^FOO");

    auto AST = createPatchedAST(Baseline, Modified.code());
    ASSERT_TRUE(AST);

    const auto &SM = AST->getSourceManager();
    auto *MacroTok = AST->getTokens().spelledTokenAt(
        SM.getComposedLoc(SM.getMainFileID(), Modified.point()));
    ASSERT_TRUE(MacroTok);

    auto FoundMacro = locateMacroAt(*MacroTok, AST->getPreprocessor());
    ASSERT_TRUE(FoundMacro);
    EXPECT_THAT(FoundMacro->Name, "FOO");
    auto HI =
        getHover(*AST, offsetToPosition(Modified.code(), Modified.point()),
                 format::getLLVMStyle(), nullptr);
    ASSERT_TRUE(HI);
    EXPECT_THAT(HI->Definition, testing::IsEmpty());
  }

  {
    // Offset is valid, but underlying text is different.
    llvm::StringLiteral Baseline = "#define FOO";
    Annotations Modified(R"cpp(#define BAR
    ^FOO")cpp");

    auto AST = createPatchedAST(Baseline, Modified.code());
    ASSERT_TRUE(AST);

    auto HI = getHover(*AST, Modified.point(), format::getLLVMStyle(), nullptr);
    ASSERT_TRUE(HI);
    EXPECT_THAT(HI->Definition, "#define BAR");
  }
}

TEST(PreamblePatchTest, RefsToMacros) {
  struct {
    const char *const Baseline;
    const char *const Modified;
  } Cases[] = {
      // Newly added
      {
          "",
          R"cpp(
            #define ^FOO
            ^[[FOO]])cpp",
      },
      // Moved around
      {
          "#define FOO",
          R"cpp(
            #define BAR
            #define ^FOO
            ^[[FOO]])cpp",
      },
      // Ref in preamble section
      {
          "",
          R"cpp(
            #define ^FOO
            #undef ^FOO)cpp",
      },
  };

  for (const auto &Case : Cases) {
    Annotations Modified(Case.Modified);
    auto AST = createPatchedAST("", Modified.code());
    ASSERT_TRUE(AST);

    const auto &SM = AST->getSourceManager();
    std::vector<Matcher<Location>> ExpectedLocations;
    for (const auto &R : Modified.ranges())
      ExpectedLocations.push_back(Field(&Location::range, R));

    for (const auto &P : Modified.points()) {
      auto *MacroTok = AST->getTokens().spelledTokenAt(SM.getComposedLoc(
          SM.getMainFileID(),
          llvm::cantFail(positionToOffset(Modified.code(), P))));
      ASSERT_TRUE(MacroTok);
      EXPECT_THAT(findReferences(*AST, P, 0).References,
                  testing::ElementsAreArray(ExpectedLocations));
    }
  }
}

TEST(TranslatePreamblePatchLocation, Simple) {
  auto TU = TestTU::withHeaderCode(R"cpp(
    #line 3 "main.cpp"
    int foo();)cpp");
  // Presumed line/col needs to be valid in the main file.
  TU.Code = R"cpp(// line 1
    // line 2
    // line 3
    // line 4)cpp";
  TU.Filename = "main.cpp";
  TU.HeaderFilename = "__preamble_patch__.h";
  TU.ImplicitHeaderGuard = false;

  auto AST = TU.build();
  auto &SM = AST.getSourceManager();
  auto &ND = findDecl(AST, "foo");
  EXPECT_NE(SM.getFileID(ND.getLocation()), SM.getMainFileID());

  auto TranslatedLoc = translatePreamblePatchLocation(ND.getLocation(), SM);
  auto DecompLoc = SM.getDecomposedLoc(TranslatedLoc);
  EXPECT_EQ(DecompLoc.first, SM.getMainFileID());
  EXPECT_EQ(SM.getLineNumber(DecompLoc.first, DecompLoc.second), 3U);
}

TEST(PreamblePatch, ModifiedBounds) {
  struct {
    const char *const Baseline;
    const char *const Modified;
  } Cases[] = {
      // Size increased
      {
          "",
          R"cpp(
            #define FOO
            FOO)cpp",
      },
      // Stayed same
      {"#define FOO", "#define BAR"},
      // Got smaller
      {
          R"cpp(
            #define FOO
            #undef FOO)cpp",
          "#define FOO"},
  };

  for (const auto &Case : Cases) {
    auto TU = TestTU::withCode(Case.Baseline);
    auto BaselinePreamble = TU.preamble();
    ASSERT_TRUE(BaselinePreamble);

    Annotations Modified(Case.Modified);
    TU.Code = Modified.code().str();
    MockFS FS;
    auto PP = PreamblePatch::create(testPath(TU.Filename), TU.inputs(FS),
                                    *BaselinePreamble);

    IgnoreDiagnostics Diags;
    auto CI = buildCompilerInvocation(TU.inputs(FS), Diags);
    ASSERT_TRUE(CI);

    const auto ExpectedBounds =
        Lexer::ComputePreamble(Case.Modified, *CI->getLangOpts());
    EXPECT_EQ(PP.modifiedBounds().Size, ExpectedBounds.Size);
    EXPECT_EQ(PP.modifiedBounds().PreambleEndsAtStartOfLine,
              ExpectedBounds.PreambleEndsAtStartOfLine);
  }
}
} // namespace
} // namespace clangd
} // namespace clang
