//===- unittests/Basic/SarifTest.cpp - Test writing SARIF documents -------===//
//
// 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/Basic/Sarif.h"
#include "clang/Basic/DiagnosticOptions.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/FileSystemOptions.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/SourceManager.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/JSON.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/VirtualFileSystem.h"
#include "llvm/Support/raw_ostream.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"

#include <algorithm>

using namespace clang;

namespace {

using LineCol = std::pair<unsigned int, unsigned int>;

static std::string serializeSarifDocument(llvm::json::Object &&Doc) {
  std::string Output;
  llvm::json::Value Value(std::move(Doc));
  llvm::raw_string_ostream OS{Output};
  OS << llvm::formatv("{0}", Value);
  OS.flush();
  return Output;
}

class SarifDocumentWriterTest : public ::testing::Test {
protected:
  SarifDocumentWriterTest()
      : InMemoryFileSystem(new llvm::vfs::InMemoryFileSystem),
        FileMgr(FileSystemOptions(), InMemoryFileSystem),
        DiagID(new DiagnosticIDs()), DiagOpts(new DiagnosticOptions()),
        Diags(DiagID, DiagOpts.get(), new IgnoringDiagConsumer()),
        SourceMgr(Diags, FileMgr) {}

  IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemoryFileSystem;
  FileManager FileMgr;
  IntrusiveRefCntPtr<DiagnosticIDs> DiagID;
  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts;
  DiagnosticsEngine Diags;
  SourceManager SourceMgr;
  LangOptions LangOpts;

  FileID registerSource(llvm::StringRef Name, const char *SourceText,
                        bool IsMainFile = false) {
    std::unique_ptr<llvm::MemoryBuffer> SourceBuf =
        llvm::MemoryBuffer::getMemBuffer(SourceText);
    FileEntryRef SourceFile =
        FileMgr.getVirtualFileRef(Name, SourceBuf->getBufferSize(), 0);
    SourceMgr.overrideFileContents(SourceFile, std::move(SourceBuf));
    FileID FID = SourceMgr.getOrCreateFileID(SourceFile, SrcMgr::C_User);
    if (IsMainFile)
      SourceMgr.setMainFileID(FID);
    return FID;
  }

  CharSourceRange getFakeCharSourceRange(FileID FID, LineCol Begin,
                                         LineCol End) {
    auto BeginLoc = SourceMgr.translateLineCol(FID, Begin.first, Begin.second);
    auto EndLoc = SourceMgr.translateLineCol(FID, End.first, End.second);
    return CharSourceRange{SourceRange{BeginLoc, EndLoc}, /* ITR = */ false};
  }
};

TEST_F(SarifDocumentWriterTest, canCreateEmptyDocument) {
  // GIVEN:
  SarifDocumentWriter Writer{SourceMgr};

  // WHEN:
  const llvm::json::Object &EmptyDoc = Writer.createDocument();
  std::vector<StringRef> Keys(EmptyDoc.size());
  std::transform(EmptyDoc.begin(), EmptyDoc.end(), Keys.begin(),
                 [](auto Item) { return Item.getFirst(); });

  // THEN:
  ASSERT_THAT(Keys, testing::UnorderedElementsAre("$schema", "version"));
}

// Test that a newly inserted run will associate correct tool names
TEST_F(SarifDocumentWriterTest, canCreateDocumentWithOneRun) {
  // GIVEN:
  SarifDocumentWriter Writer{SourceMgr};
  const char *ShortName = "sariftest";
  const char *LongName = "sarif writer test";

  // WHEN:
  Writer.createRun(ShortName, LongName);
  Writer.endRun();
  const llvm::json::Object &Doc = Writer.createDocument();
  const llvm::json::Array *Runs = Doc.getArray("runs");

  // THEN:
  // A run was created
  ASSERT_THAT(Runs, testing::NotNull());

  // It is the only run
  ASSERT_EQ(Runs->size(), 1UL);

  // The tool associated with the run was the tool
  const llvm::json::Object *Driver =
      Runs->begin()->getAsObject()->getObject("tool")->getObject("driver");
  ASSERT_THAT(Driver, testing::NotNull());

  ASSERT_TRUE(Driver->getString("name").has_value());
  ASSERT_TRUE(Driver->getString("fullName").has_value());
  ASSERT_TRUE(Driver->getString("language").has_value());

  EXPECT_EQ(*Driver->getString("name"), ShortName);
  EXPECT_EQ(*Driver->getString("fullName"), LongName);
  EXPECT_EQ(*Driver->getString("language"), "en-US");
}

TEST_F(SarifDocumentWriterTest, addingResultsWillCrashIfThereIsNoRun) {
#if defined(NDEBUG) || !GTEST_HAS_DEATH_TEST
  GTEST_SKIP() << "This death test is only available for debug builds.";
#endif
  // GIVEN:
  SarifDocumentWriter Writer{SourceMgr};

  // WHEN:
  //  A SarifDocumentWriter::createRun(...) was not called prior to
  //  SarifDocumentWriter::appendResult(...)
  // But a rule exists
  auto RuleIdx = Writer.createRule(SarifRule::create());
  const SarifResult &EmptyResult = SarifResult::create(RuleIdx);

  // THEN:
  auto Matcher = ::testing::AnyOf(
      ::testing::HasSubstr("create a run first"),
      ::testing::HasSubstr("no runs associated with the document"));
  ASSERT_DEATH(Writer.appendResult(EmptyResult), Matcher);
}

TEST_F(SarifDocumentWriterTest, settingInvalidRankWillCrash) {
#if defined(NDEBUG) || !GTEST_HAS_DEATH_TEST
  GTEST_SKIP() << "This death test is only available for debug builds.";
#endif
  // GIVEN:
  SarifDocumentWriter Writer{SourceMgr};

  // WHEN:
  // A SarifReportingConfiguration is created with an invalid "rank"
  // * Ranks below 0.0 are invalid
  // * Ranks above 100.0 are invalid

  // THEN: The builder will crash in either case
  EXPECT_DEATH(SarifReportingConfiguration::create().setRank(-1.0),
               ::testing::HasSubstr("Rule rank cannot be smaller than 0.0"));
  EXPECT_DEATH(SarifReportingConfiguration::create().setRank(101.0),
               ::testing::HasSubstr("Rule rank cannot be larger than 100.0"));
}

TEST_F(SarifDocumentWriterTest, creatingResultWithDisabledRuleWillCrash) {
#if defined(NDEBUG) || !GTEST_HAS_DEATH_TEST
  GTEST_SKIP() << "This death test is only available for debug builds.";
#endif

  // GIVEN:
  SarifDocumentWriter Writer{SourceMgr};

  // WHEN:
  // A disabled Rule is created, and a result is create referencing this rule
  const auto &Config = SarifReportingConfiguration::create().disable();
  auto RuleIdx =
      Writer.createRule(SarifRule::create().setDefaultConfiguration(Config));
  const SarifResult &Result = SarifResult::create(RuleIdx);

  // THEN:
  // SarifResult::create(...) will produce a crash
  ASSERT_DEATH(
      Writer.appendResult(Result),
      ::testing::HasSubstr("Cannot add a result referencing a disabled Rule"));
}

// Test adding rule and result shows up in the final document
TEST_F(SarifDocumentWriterTest, addingResultWithValidRuleAndRunIsOk) {
  // GIVEN:
  SarifDocumentWriter Writer{SourceMgr};
  const SarifRule &Rule =
      SarifRule::create()
          .setRuleId("clang.unittest")
          .setDescription("Example rule created during unit tests")
          .setName("clang unit test");

  // WHEN:
  Writer.createRun("sarif test", "sarif test runner");
  unsigned RuleIdx = Writer.createRule(Rule);
  const SarifResult &Result = SarifResult::create(RuleIdx);

  Writer.appendResult(Result);
  const llvm::json::Object &Doc = Writer.createDocument();

  // THEN:
  // A document with a valid schema and version exists
  ASSERT_THAT(Doc.get("$schema"), ::testing::NotNull());
  ASSERT_THAT(Doc.get("version"), ::testing::NotNull());
  const llvm::json::Array *Runs = Doc.getArray("runs");

  // A run exists on this document
  ASSERT_THAT(Runs, ::testing::NotNull());
  ASSERT_EQ(Runs->size(), 1UL);
  const llvm::json::Object *TheRun = Runs->back().getAsObject();

  // The run has slots for tools, results, rules and artifacts
  ASSERT_THAT(TheRun->get("tool"), ::testing::NotNull());
  ASSERT_THAT(TheRun->get("results"), ::testing::NotNull());
  ASSERT_THAT(TheRun->get("artifacts"), ::testing::NotNull());
  const llvm::json::Object *Driver =
      TheRun->getObject("tool")->getObject("driver");
  const llvm::json::Array *Results = TheRun->getArray("results");
  const llvm::json::Array *Artifacts = TheRun->getArray("artifacts");

  // The tool is as expected
  ASSERT_TRUE(Driver->getString("name").has_value());
  ASSERT_TRUE(Driver->getString("fullName").has_value());

  EXPECT_EQ(*Driver->getString("name"), "sarif test");
  EXPECT_EQ(*Driver->getString("fullName"), "sarif test runner");

  // The results are as expected
  EXPECT_EQ(Results->size(), 1UL);

  // The artifacts are as expected
  EXPECT_TRUE(Artifacts->empty());
}

TEST_F(SarifDocumentWriterTest, checkSerializingResultsWithDefaultRuleConfig) {
  // GIVEN:
  const std::string ExpectedOutput =
      R"({"$schema":"https://docs.oasis-open.org/sarif/sarif/v2.1.0/cos02/schemas/sarif-schema-2.1.0.json","runs":[{"artifacts":[],"columnKind":"unicodeCodePoints","results":[{"level":"warning","message":{"text":""},"ruleId":"clang.unittest","ruleIndex":0}],"tool":{"driver":{"fullName":"sarif test runner","informationUri":"https://clang.llvm.org/docs/UsersManual.html","language":"en-US","name":"sarif test","rules":[{"defaultConfiguration":{"enabled":true,"level":"warning","rank":-1},"fullDescription":{"text":"Example rule created during unit tests"},"id":"clang.unittest","name":"clang unit test"}],"version":"1.0.0"}}}],"version":"2.1.0"})";

  SarifDocumentWriter Writer{SourceMgr};
  const SarifRule &Rule =
      SarifRule::create()
          .setRuleId("clang.unittest")
          .setDescription("Example rule created during unit tests")
          .setName("clang unit test");

  // WHEN: A run contains a result
  Writer.createRun("sarif test", "sarif test runner", "1.0.0");
  unsigned RuleIdx = Writer.createRule(Rule);
  const SarifResult &Result = SarifResult::create(RuleIdx);
  Writer.appendResult(Result);
  std::string Output = serializeSarifDocument(Writer.createDocument());

  // THEN:
  ASSERT_THAT(Output, ::testing::StrEq(ExpectedOutput));
}

TEST_F(SarifDocumentWriterTest, checkSerializingResultsWithCustomRuleConfig) {
  // GIVEN:
  const std::string ExpectedOutput =
      R"({"$schema":"https://docs.oasis-open.org/sarif/sarif/v2.1.0/cos02/schemas/sarif-schema-2.1.0.json","runs":[{"artifacts":[],"columnKind":"unicodeCodePoints","results":[{"level":"error","message":{"text":""},"ruleId":"clang.unittest","ruleIndex":0}],"tool":{"driver":{"fullName":"sarif test runner","informationUri":"https://clang.llvm.org/docs/UsersManual.html","language":"en-US","name":"sarif test","rules":[{"defaultConfiguration":{"enabled":true,"level":"error","rank":35.5},"fullDescription":{"text":"Example rule created during unit tests"},"id":"clang.unittest","name":"clang unit test"}],"version":"1.0.0"}}}],"version":"2.1.0"})";

  SarifDocumentWriter Writer{SourceMgr};
  const SarifRule &Rule =
      SarifRule::create()
          .setRuleId("clang.unittest")
          .setDescription("Example rule created during unit tests")
          .setName("clang unit test")
          .setDefaultConfiguration(SarifReportingConfiguration::create()
                                       .setLevel(SarifResultLevel::Error)
                                       .setRank(35.5));

  // WHEN: A run contains a result
  Writer.createRun("sarif test", "sarif test runner", "1.0.0");
  unsigned RuleIdx = Writer.createRule(Rule);
  const SarifResult &Result = SarifResult::create(RuleIdx);
  Writer.appendResult(Result);
  std::string Output = serializeSarifDocument(Writer.createDocument());

  // THEN:
  ASSERT_THAT(Output, ::testing::StrEq(ExpectedOutput));
}

// Check that serializing artifacts from results produces valid SARIF
TEST_F(SarifDocumentWriterTest, checkSerializingArtifacts) {
  // GIVEN:
  const std::string ExpectedOutput =
      R"({"$schema":"https://docs.oasis-open.org/sarif/sarif/v2.1.0/cos02/schemas/sarif-schema-2.1.0.json","runs":[{"artifacts":[{"length":40,"location":{"index":0,"uri":"file:///main.cpp"},"mimeType":"text/plain","roles":["resultFile"]}],"columnKind":"unicodeCodePoints","results":[{"level":"error","locations":[{"physicalLocation":{"artifactLocation":{"index":0,"uri":"file:///main.cpp"},"region":{"endColumn":14,"startColumn":14,"startLine":3}}}],"message":{"text":"expected ';' after top level declarator"},"ruleId":"clang.unittest","ruleIndex":0}],"tool":{"driver":{"fullName":"sarif test runner","informationUri":"https://clang.llvm.org/docs/UsersManual.html","language":"en-US","name":"sarif test","rules":[{"defaultConfiguration":{"enabled":true,"level":"warning","rank":-1},"fullDescription":{"text":"Example rule created during unit tests"},"id":"clang.unittest","name":"clang unit test"}],"version":"1.0.0"}}}],"version":"2.1.0"})";

  SarifDocumentWriter Writer{SourceMgr};
  const SarifRule &Rule =
      SarifRule::create()
          .setRuleId("clang.unittest")
          .setDescription("Example rule created during unit tests")
          .setName("clang unit test");

  // WHEN: A result is added with valid source locations for its diagnostics
  Writer.createRun("sarif test", "sarif test runner", "1.0.0");
  unsigned RuleIdx = Writer.createRule(Rule);

  llvm::SmallVector<CharSourceRange, 1> DiagLocs;
  const char *SourceText = "int foo = 0;\n"
                           "int bar = 1;\n"
                           "float x = 0.0\n";

  FileID MainFileID =
      registerSource("/main.cpp", SourceText, /* IsMainFile = */ true);
  CharSourceRange SourceCSR =
      getFakeCharSourceRange(MainFileID, {3, 14}, {3, 14});

  DiagLocs.push_back(SourceCSR);

  const SarifResult &Result =
      SarifResult::create(RuleIdx)
          .setLocations(DiagLocs)
          .setDiagnosticMessage("expected ';' after top level declarator")
          .setDiagnosticLevel(SarifResultLevel::Error);
  Writer.appendResult(Result);
  std::string Output = serializeSarifDocument(Writer.createDocument());

  // THEN: Assert that the serialized SARIF is as expected
  ASSERT_THAT(Output, ::testing::StrEq(ExpectedOutput));
}

TEST_F(SarifDocumentWriterTest, checkSerializingCodeflows) {
  // GIVEN:
  const std::string ExpectedOutput =
      R"({"$schema":"https://docs.oasis-open.org/sarif/sarif/v2.1.0/cos02/schemas/sarif-schema-2.1.0.json","runs":[{"artifacts":[{"length":41,"location":{"index":0,"uri":"file:///main.cpp"},"mimeType":"text/plain","roles":["resultFile"]},{"length":27,"location":{"index":1,"uri":"file:///test-header-1.h"},"mimeType":"text/plain","roles":["resultFile"]},{"length":30,"location":{"index":2,"uri":"file:///test-header-2.h"},"mimeType":"text/plain","roles":["resultFile"]},{"length":28,"location":{"index":3,"uri":"file:///test-header-3.h"},"mimeType":"text/plain","roles":["resultFile"]}],"columnKind":"unicodeCodePoints","results":[{"codeFlows":[{"threadFlows":[{"locations":[{"importance":"essential","location":{"message":{"text":"Message #1"},"physicalLocation":{"artifactLocation":{"index":1,"uri":"file:///test-header-1.h"},"region":{"endColumn":8,"endLine":2,"startColumn":1,"startLine":1}}}},{"importance":"important","location":{"message":{"text":"Message #2"},"physicalLocation":{"artifactLocation":{"index":2,"uri":"file:///test-header-2.h"},"region":{"endColumn":8,"endLine":2,"startColumn":1,"startLine":1}}}},{"importance":"unimportant","location":{"message":{"text":"Message #3"},"physicalLocation":{"artifactLocation":{"index":3,"uri":"file:///test-header-3.h"},"region":{"endColumn":8,"endLine":2,"startColumn":1,"startLine":1}}}}]}]}],"level":"warning","locations":[{"physicalLocation":{"artifactLocation":{"index":0,"uri":"file:///main.cpp"},"region":{"endColumn":8,"endLine":2,"startColumn":5,"startLine":2}}}],"message":{"text":"Redefinition of 'foo'"},"ruleId":"clang.unittest","ruleIndex":0}],"tool":{"driver":{"fullName":"sarif test runner","informationUri":"https://clang.llvm.org/docs/UsersManual.html","language":"en-US","name":"sarif test","rules":[{"defaultConfiguration":{"enabled":true,"level":"warning","rank":-1},"fullDescription":{"text":"Example rule created during unit tests"},"id":"clang.unittest","name":"clang unit test"}],"version":"1.0.0"}}}],"version":"2.1.0"})";

  const char *SourceText = "int foo = 0;\n"
                           "int foo = 1;\n"
                           "float x = 0.0;\n";
  FileID MainFileID =
      registerSource("/main.cpp", SourceText, /* IsMainFile = */ true);
  CharSourceRange DiagLoc{getFakeCharSourceRange(MainFileID, {2, 5}, {2, 8})};

  SarifDocumentWriter Writer{SourceMgr};
  const SarifRule &Rule =
      SarifRule::create()
          .setRuleId("clang.unittest")
          .setDescription("Example rule created during unit tests")
          .setName("clang unit test");

  constexpr unsigned int NumCases = 3;
  llvm::SmallVector<ThreadFlow, NumCases> Threadflows;
  const char *HeaderTexts[NumCases]{("#pragma once\n"
                                     "#include <foo>"),
                                    ("#ifndef FOO\n"
                                     "#define FOO\n"
                                     "#endif"),
                                    ("#ifdef FOO\n"
                                     "#undef FOO\n"
                                     "#endif")};
  const char *HeaderNames[NumCases]{"/test-header-1.h", "/test-header-2.h",
                                    "/test-header-3.h"};
  ThreadFlowImportance Importances[NumCases]{ThreadFlowImportance::Essential,
                                             ThreadFlowImportance::Important,
                                             ThreadFlowImportance::Unimportant};
  for (size_t Idx = 0; Idx != NumCases; ++Idx) {
    FileID FID = registerSource(HeaderNames[Idx], HeaderTexts[Idx]);
    CharSourceRange &&CSR = getFakeCharSourceRange(FID, {1, 1}, {2, 8});
    std::string Message = llvm::formatv("Message #{0}", Idx + 1);
    ThreadFlow Item = ThreadFlow::create()
                          .setRange(CSR)
                          .setImportance(Importances[Idx])
                          .setMessage(Message);
    Threadflows.push_back(Item);
  }

  // WHEN: A result containing code flows and diagnostic locations is added
  Writer.createRun("sarif test", "sarif test runner", "1.0.0");
  unsigned RuleIdx = Writer.createRule(Rule);
  const SarifResult &Result =
      SarifResult::create(RuleIdx)
          .setLocations({DiagLoc})
          .setDiagnosticMessage("Redefinition of 'foo'")
          .setThreadFlows(Threadflows)
          .setDiagnosticLevel(SarifResultLevel::Warning);
  Writer.appendResult(Result);
  std::string Output = serializeSarifDocument(Writer.createDocument());

  // THEN: Assert that the serialized SARIF is as expected
  ASSERT_THAT(Output, ::testing::StrEq(ExpectedOutput));
}

} // namespace
