//===- llvm/unittest/DebugInfo/LogicalView/ELFReaderTest.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 "llvm/DebugInfo/LogicalView/Core/LVCompare.h"
#include "llvm/DebugInfo/LogicalView/Core/LVLine.h"
#include "llvm/DebugInfo/LogicalView/Core/LVScope.h"
#include "llvm/DebugInfo/LogicalView/Core/LVSymbol.h"
#include "llvm/DebugInfo/LogicalView/Core/LVType.h"
#include "llvm/DebugInfo/LogicalView/LVReaderHandler.h"
#include "llvm/MC/TargetRegistry.h"
#include "llvm/Support/COM.h"
#include "llvm/Support/InitLLVM.h"
#include "llvm/Support/ScopedPrinter.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/ToolOutputFile.h"
#include "llvm/Testing/Support/Error.h"

#include "gtest/gtest.h"

using namespace llvm;
using namespace llvm::logicalview;

extern const char *TestMainArgv0;

namespace {

const char *DwarfClang = "test-dwarf-clang.o";
const char *DwarfGcc = "test-dwarf-gcc.o";

// Helper function to get the first compile unit.
LVScopeCompileUnit *getFirstCompileUnit(LVScopeRoot *Root) {
  EXPECT_NE(Root, nullptr);
  const LVScopes *CompileUnits = Root->getScopes();
  EXPECT_NE(CompileUnits, nullptr);
  EXPECT_EQ(CompileUnits->size(), 1u);

  LVScopes::const_iterator Iter = CompileUnits->begin();
  EXPECT_NE(Iter, nullptr);
  LVScopeCompileUnit *CompileUnit = static_cast<LVScopeCompileUnit *>(*Iter);
  EXPECT_NE(CompileUnit, nullptr);
  return CompileUnit;
}

// Helper function to create a reader.
std::unique_ptr<LVReader> createReader(LVReaderHandler &ReaderHandler,
                                       SmallString<128> &InputsDir,
                                       StringRef Filename) {
  SmallString<128> ObjectName(InputsDir);
  llvm::sys::path::append(ObjectName, Filename);

  Expected<std::unique_ptr<LVReader>> ReaderOrErr =
      ReaderHandler.createReader(std::string(ObjectName));
  EXPECT_THAT_EXPECTED(ReaderOrErr, Succeeded());
  std::unique_ptr<LVReader> Reader = std::move(*ReaderOrErr);
  EXPECT_NE(Reader, nullptr);
  return Reader;
}

// Check the logical elements basic properties.
void checkElementProperties(LVReader *Reader) {
  LVScopeRoot *Root = Reader->getScopesRoot();
  LVScopeCompileUnit *CompileUnit = getFirstCompileUnit(Root);

  EXPECT_EQ(Root->getFileFormatName(), "elf64-x86-64");
  EXPECT_EQ(Root->getName(), DwarfClang);

  EXPECT_EQ(CompileUnit->getBaseAddress(), 0u);
  EXPECT_TRUE(CompileUnit->getProducer().startswith("clang"));
  EXPECT_EQ(CompileUnit->getName(), "test.cpp");

  EXPECT_EQ(CompileUnit->lineCount(), 0u);
  EXPECT_EQ(CompileUnit->scopeCount(), 1u);
  EXPECT_EQ(CompileUnit->symbolCount(), 0u);
  EXPECT_EQ(CompileUnit->typeCount(), 7u);
  EXPECT_EQ(CompileUnit->rangeCount(), 1u);

  const LVLocations *Ranges = CompileUnit->getRanges();
  ASSERT_NE(Ranges, nullptr);
  ASSERT_EQ(Ranges->size(), 1u);
  LVLocations::const_iterator IterLocation = Ranges->begin();
  LVLocation *Location = (*IterLocation);
  EXPECT_STREQ(Location->getIntervalInfo().c_str(),
               "{Range} Lines 2:9 [0x0000000000:0x000000003a]");

  LVRange RangeList;
  CompileUnit->getRanges(RangeList);

  const LVRangeEntries &RangeEntries = RangeList.getEntries();
  ASSERT_EQ(RangeEntries.size(), 2u);
  LVRangeEntries::const_iterator IterRanges = RangeEntries.cbegin();
  LVRangeEntry RangeEntry = *IterRanges;
  EXPECT_EQ(RangeEntry.lower(), 0u);
  EXPECT_EQ(RangeEntry.upper(), 0x3au);
  EXPECT_EQ(RangeEntry.scope()->getLineNumber(), 0u);
  EXPECT_EQ(RangeEntry.scope()->getName(), "test.cpp");
  EXPECT_EQ(RangeEntry.scope()->getOffset(), 0x0bu);

  ++IterRanges;
  RangeEntry = *IterRanges;
  EXPECT_EQ(RangeEntry.lower(), 0x1cu);
  EXPECT_EQ(RangeEntry.upper(), 0x2fu);
  EXPECT_EQ(RangeEntry.scope()->getLineNumber(), 0u);
  EXPECT_EQ(RangeEntry.scope()->getName(), "foo::?");
  EXPECT_EQ(RangeEntry.scope()->getOffset(), 0x71u);

  const LVPublicNames &PublicNames = CompileUnit->getPublicNames();
  ASSERT_EQ(PublicNames.size(), 1u);
  LVPublicNames::const_iterator IterNames = PublicNames.cbegin();
  LVScope *Function = (*IterNames).first;
  EXPECT_EQ(Function->getName(), "foo");
  EXPECT_EQ(Function->getLineNumber(), 2u);
  LVNameInfo NameInfo = (*IterNames).second;
  EXPECT_EQ(NameInfo.first, 0u);
  EXPECT_EQ(NameInfo.second, 0x3au);

  // Lines (debug and assembler) for 'foo'.
  const LVLines *Lines = Function->getLines();
  ASSERT_NE(Lines, nullptr);
  ASSERT_EQ(Lines->size(), 0x12u);
}

// Check the logical elements selection.
void checkElementSelection(LVReader *Reader) {
  LVScopeRoot *Root = Reader->getScopesRoot();
  LVScopeCompileUnit *CompileUnit = getFirstCompileUnit(Root);

  // Get the matched elements.
  LVElements MatchedElements = CompileUnit->getMatchedElements();
  std::map<LVOffset, LVElement *> MapElements;
  for (LVElement *Element : MatchedElements)
    MapElements[Element->getOffset()] = Element;
  ASSERT_EQ(MapElements.size(), 0xeu);

  LVElement *Element = MapElements[0x000000004b]; // 'foo'
  ASSERT_NE(Element, nullptr);
  EXPECT_NE(Element->getName().find("foo"), StringRef::npos);
  EXPECT_EQ(Element->getIsScope(), 1);

  Element = MapElements[0x00000000c0]; // 'CONSTANT'
  ASSERT_NE(Element, nullptr);
  EXPECT_NE(Element->getName().find("CONSTANT"), StringRef::npos);
  EXPECT_EQ(Element->getIsSymbol(), 1);

  Element = MapElements[0x000000002d]; // 'INTPTR'
  ASSERT_NE(Element, nullptr);
  EXPECT_NE(Element->getName().find("INTPTR"), StringRef::npos);
  EXPECT_EQ(Element->getIsType(), 1);

  Element = MapElements[0x00000000af]; // 'INTEGER'
  ASSERT_NE(Element, nullptr);
  EXPECT_NE(Element->getName().find("INTEGER"), StringRef::npos);
  EXPECT_EQ(Element->getIsType(), 1);

  Element = MapElements[0x000000000f]; // 'movl	%edx, %eax'
  ASSERT_NE(Element, nullptr);
  EXPECT_NE(Element->getName().find("movl"), StringRef::npos);
  EXPECT_EQ(Element->getIsLine(), 1);

  // Get the parents for the matched elements.
  LVScopes MatchedScopes = CompileUnit->getMatchedScopes();
  std::set<LVOffset> SetScopes;
  for (LVScope *Scope : MatchedScopes)
    SetScopes.insert(Scope->getOffset());
  std::set<LVOffset>::iterator Iter;
  ASSERT_EQ(SetScopes.size(), 3u);

  Iter = SetScopes.find(0x000000000b); // CompileUnit <- 'foo'
  EXPECT_NE(Iter, SetScopes.end());
  Iter = SetScopes.find(0x000000009e); // Function <- 'movl	%edx, %eax'
  EXPECT_NE(Iter, SetScopes.end());
  Iter = SetScopes.find(0x000000009e); // LexicalScope <- 'INTEGER'
  EXPECT_NE(Iter, SetScopes.end());
}

// Check the logical elements comparison.
void checkElementComparison(LVReader *Reference, LVReader *Target) {
  LVCompare Compare(nulls());
  Error Err = Compare.execute(Reference, Target);
  ASSERT_THAT_ERROR(std::move(Err), Succeeded());

  // Get comparison table.
  LVPassTable PassTable = Compare.getPassTable();
  ASSERT_EQ(PassTable.size(), 5u);

  LVReader *Reader;
  LVElement *Element;
  LVComparePass Pass;

  // Reference: Missing Variable 'CONSTANT'
  std::tie(Reader, Element, Pass) = PassTable[0];
  ASSERT_NE(Reader, nullptr);
  ASSERT_NE(Element, nullptr);
  EXPECT_EQ(Reader, Reference);
  EXPECT_EQ(Element->getLevel(), 4u);
  EXPECT_EQ(Element->getLineNumber(), 5u);
  EXPECT_EQ(Element->getName(), "CONSTANT");
  EXPECT_EQ(Pass, LVComparePass::Missing);

  // Reference: Missing TypeDefinition 'INTEGER'
  std::tie(Reader, Element, Pass) = PassTable[1];
  ASSERT_NE(Reader, nullptr);
  ASSERT_NE(Element, nullptr);
  EXPECT_EQ(Reader, Reference);
  EXPECT_EQ(Element->getLevel(), 3u);
  EXPECT_EQ(Element->getLineNumber(), 4u);
  EXPECT_EQ(Element->getName(), "INTEGER");
  EXPECT_EQ(Pass, LVComparePass::Missing);

  // Reference: Missing DebugLine
  std::tie(Reader, Element, Pass) = PassTable[2];
  ASSERT_NE(Reader, nullptr);
  ASSERT_NE(Element, nullptr);
  EXPECT_EQ(Reader, Reference);
  EXPECT_EQ(Element->getLevel(), 3u);
  EXPECT_EQ(Element->getLineNumber(), 8u);
  EXPECT_EQ(Element->getName(), "");
  EXPECT_EQ(Pass, LVComparePass::Missing);

  // Target: Added Variable 'CONSTANT'
  std::tie(Reader, Element, Pass) = PassTable[3];
  ASSERT_NE(Reader, nullptr);
  ASSERT_NE(Element, nullptr);
  EXPECT_EQ(Reader, Target);
  EXPECT_EQ(Element->getLevel(), 4u);
  EXPECT_EQ(Element->getLineNumber(), 5u);
  EXPECT_EQ(Element->getName(), "CONSTANT");
  EXPECT_EQ(Pass, LVComparePass::Added);

  // Target: Added TypeDefinition 'INTEGER'
  std::tie(Reader, Element, Pass) = PassTable[4];
  ASSERT_NE(Reader, nullptr);
  ASSERT_NE(Element, nullptr);
  EXPECT_EQ(Reader, Target);
  EXPECT_EQ(Element->getLevel(), 4u);
  EXPECT_EQ(Element->getLineNumber(), 4u);
  EXPECT_EQ(Element->getName(), "INTEGER");
  EXPECT_EQ(Pass, LVComparePass::Added);
}

// Logical elements properties.
void elementProperties(SmallString<128> &InputsDir) {
  // Reader options.
  LVOptions ReaderOptions;
  ReaderOptions.setAttributeOffset();
  ReaderOptions.setAttributeFormat();
  ReaderOptions.setAttributeFilename();
  ReaderOptions.setAttributeProducer();
  ReaderOptions.setAttributePublics();
  ReaderOptions.setAttributeRange();
  ReaderOptions.setAttributeLocation();
  ReaderOptions.setPrintAll();
  ReaderOptions.resolveDependencies();

  std::vector<std::string> Objects;
  ScopedPrinter W(outs());
  LVReaderHandler ReaderHandler(Objects, W, ReaderOptions);

  // Check logical elements properties.
  std::unique_ptr<LVReader> Reader =
      createReader(ReaderHandler, InputsDir, DwarfClang);
  checkElementProperties(Reader.get());
}

// Logical elements selection.
void elementSelection(SmallString<128> &InputsDir) {
  // Reader options.
  LVOptions ReaderOptions;
  ReaderOptions.setAttributeOffset();
  ReaderOptions.setPrintAll();

  ReaderOptions.setSelectIgnoreCase();
  ReaderOptions.setSelectUseRegex();

  ReaderOptions.setReportList(); // Matched elements.
  ReaderOptions.setReportView(); // Parents for matched elements.

  // Add patterns.
  ReaderOptions.Select.Generic.insert("foo");
  ReaderOptions.Select.Generic.insert("movl[ \t]?%");
  ReaderOptions.Select.Generic.insert("INT[a-z]*");
  ReaderOptions.Select.Generic.insert("CONSTANT");

  ReaderOptions.resolveDependencies();

  std::vector<std::string> Objects;
  ScopedPrinter W(outs());
  LVReaderHandler ReaderHandler(Objects, W, ReaderOptions);

  // Check logical elements selection.
  std::unique_ptr<LVReader> Reader =
      createReader(ReaderHandler, InputsDir, DwarfGcc);
  checkElementSelection(Reader.get());
}

// Compare logical elements.
void compareElements(SmallString<128> &InputsDir) {
  // Reader options.
  LVOptions ReaderOptions;
  ReaderOptions.setAttributeOffset();
  ReaderOptions.setPrintLines();
  ReaderOptions.setPrintSymbols();
  ReaderOptions.setPrintTypes();
  ReaderOptions.setCompareLines();
  ReaderOptions.setCompareSymbols();
  ReaderOptions.setCompareTypes();

  ReaderOptions.resolveDependencies();

  std::vector<std::string> Objects;
  ScopedPrinter W(outs());
  LVReaderHandler ReaderHandler(Objects, W, ReaderOptions);

  // Check logical comparison.
  std::unique_ptr<LVReader> Reference =
      createReader(ReaderHandler, InputsDir, DwarfClang);
  std::unique_ptr<LVReader> Target =
      createReader(ReaderHandler, InputsDir, DwarfGcc);
  checkElementComparison(Reference.get(), Target.get());
}

TEST(LogicalViewTest, ELFReader) {
  // Initialize targets and assembly printers/parsers.
  llvm::InitializeAllTargetInfos();
  llvm::InitializeAllTargetMCs();
  InitializeAllDisassemblers();

  llvm::sys::InitializeCOMRAII COM(llvm::sys::COMThreadingMode::MultiThreaded);

  // This test requires a x86-registered-target.
  Triple TT;
  TT.setArch(Triple::x86_64);
  TT.setVendor(Triple::UnknownVendor);
  TT.setOS(Triple::UnknownOS);

  std::string TargetLookupError;
  if (!TargetRegistry::lookupTarget(std::string(TT.str()), TargetLookupError))
    GTEST_SKIP();

  SmallString<128> InputsDir = unittest::getInputFileDirectory(TestMainArgv0);

  // Logical elements general properties and selection.
  elementProperties(InputsDir);
  elementSelection(InputsDir);

  // Compare logical elements.
  compareElements(InputsDir);
}

} // namespace
