//===-- TestLineEntry.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 "gtest/gtest.h"
#include <iostream>
#include <optional>

#include "Plugins/ObjectFile/Mach-O/ObjectFileMachO.h"
#include "Plugins/SymbolFile/DWARF/DWARFASTParserClang.h"
#include "Plugins/SymbolFile/DWARF/SymbolFileDWARF.h"
#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "TestingSupport/SubsystemRAII.h"
#include "TestingSupport/TestUtilities.h"

#include "lldb/Core/Module.h"
#include "lldb/Host/FileSystem.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/SymbolContext.h"

#include "llvm/Support/FileUtilities.h"
#include "llvm/Support/Program.h"
#include "llvm/Testing/Support/Error.h"

using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::plugin::dwarf;

class LineEntryTest : public testing::Test {
  SubsystemRAII<FileSystem, HostInfo, ObjectFileMachO, SymbolFileDWARF,
                TypeSystemClang>
      subsystem;

public:
  void SetUp() override;

protected:
  llvm::Expected<SymbolContextList>
  GetLineEntriesForLine(uint32_t line, std::optional<uint16_t> column);
  std::optional<TestFile> m_file;
  ModuleSP m_module_sp;
};

void LineEntryTest::SetUp() {
  auto ExpectedFile = TestFile::fromYamlFile("inlined-functions.yaml");
  ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded());
  m_file.emplace(std::move(*ExpectedFile));
  m_module_sp = std::make_shared<Module>(m_file->moduleSpec());
}

  // TODO: Handle SourceLocationSpec column information
llvm::Expected<SymbolContextList> LineEntryTest::GetLineEntriesForLine(
    uint32_t line, std::optional<uint16_t> column = std::nullopt) {
  SymbolContextList sc_comp_units;
  SymbolContextList sc_line_entries;
  FileSpec file_spec("inlined-functions.cpp");
  m_module_sp->ResolveSymbolContextsForFileSpec(
      file_spec, line, /*check_inlines=*/true, lldb::eSymbolContextCompUnit,
      sc_comp_units);
  if (sc_comp_units.GetSize() == 0)
    return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                   "No comp unit found on the test object.");

  SourceLocationSpec location_spec(file_spec, line, column,
                                   /*check_inlines=*/true,
                                   /*exact_match=*/true);

  sc_comp_units[0].comp_unit->ResolveSymbolContext(
      location_spec, eSymbolContextLineEntry, sc_line_entries);
  if (sc_line_entries.GetSize() == 0)
    return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                   "No line entry found on the test object.");
  return sc_line_entries;
}

// This tests if we can get all line entries that match the passed line, if
// no column is specified.
TEST_F(LineEntryTest, GetAllExactLineMatchesWithoutColumn) {
  auto sc_line_entries = GetLineEntriesForLine(12);
  ASSERT_THAT_EXPECTED(sc_line_entries, llvm::Succeeded());
  ASSERT_EQ(sc_line_entries->NumLineEntriesWithLine(12), 6u);
}

// This tests if we can get exact line and column matches.
TEST_F(LineEntryTest, GetAllExactLineColumnMatches) {
  auto sc_line_entries = GetLineEntriesForLine(12, 39);
  ASSERT_THAT_EXPECTED(sc_line_entries, llvm::Succeeded());
  ASSERT_EQ(sc_line_entries->NumLineEntriesWithLine(12), 1u);
  auto line_entry = sc_line_entries.get()[0].line_entry;
  ASSERT_EQ(line_entry.column, 39);
}

TEST_F(LineEntryTest, GetSameLineContiguousAddressRangeNoInlines) {
  auto sc_line_entries = GetLineEntriesForLine(18);
  ASSERT_THAT_EXPECTED(sc_line_entries, llvm::Succeeded());
  auto line_entry = sc_line_entries.get()[0].line_entry;
  bool include_inlined_functions = false;
  auto range =
      line_entry.GetSameLineContiguousAddressRange(include_inlined_functions);
  ASSERT_EQ(range.GetByteSize(), (uint64_t)0x24);
}

TEST_F(LineEntryTest, GetSameLineContiguousAddressRangeOneInline) {
  auto sc_line_entries = GetLineEntriesForLine(18);
  ASSERT_THAT_EXPECTED(sc_line_entries, llvm::Succeeded());
  auto line_entry = sc_line_entries.get()[0].line_entry;
  bool include_inlined_functions = true;
  auto range =
      line_entry.GetSameLineContiguousAddressRange(include_inlined_functions);
  ASSERT_EQ(range.GetByteSize(), (uint64_t)0x49);
}

TEST_F(LineEntryTest, GetSameLineContiguousAddressRangeNestedInline) {
  auto sc_line_entries = GetLineEntriesForLine(12);
  ASSERT_THAT_EXPECTED(sc_line_entries, llvm::Succeeded());
  auto line_entry = sc_line_entries.get()[0].line_entry;
  bool include_inlined_functions = true;
  auto range =
      line_entry.GetSameLineContiguousAddressRange(include_inlined_functions);
  ASSERT_EQ(range.GetByteSize(), (uint64_t)0x33);
}

/*
# inlined-functions.cpp
inline __attribute__((always_inline)) int sum2(int a, int b) {
    int result = a + b;
    return result;
}

int sum3(int a, int b, int c) {
    int result = a + b + c;
    return result;
}

inline __attribute__((always_inline)) int sum4(int a, int b, int c, int d) {
    int result = sum2(a, b) + sum2(c, d);
    result += 0;
    return result;
}

int main(int argc, char** argv) {
    sum3(3, 4, 5) + sum2(1, 2);
    int sum = sum4(1, 2, 3, 4);
    sum2(5, 6);
    return 0;
}

// g++ -c inlined-functions.cpp -o inlined-functions.o -g -Wno-unused-value
// obj2yaml inlined-functions.o > inlined-functions.yaml

# Dump of source line per address:
# inlined-functions.cpp is src.cpp for space considerations.
0x20: src.cpp:17
0x21: src.cpp:17
0x26: src.cpp:17
0x27: src.cpp:17
0x29: src.cpp:17
0x2e: src.cpp:17
0x2f: src.cpp:17
0x31: src.cpp:17
0x36: src.cpp:18
0x37: src.cpp:18
0x39: src.cpp:18
0x3e: src.cpp:18
0x3f: src.cpp:18
0x41: src.cpp:18
0x46: src.cpp:18
0x47: src.cpp:18
0x49: src.cpp:18
0x4e: src.cpp:18
0x4f: src.cpp:18
0x51: src.cpp:18
0x56: src.cpp:18
0x57: src.cpp:18
0x59: src.cpp:18
0x5e: src.cpp:18 -> sum2@src.cpp:2
0x5f: src.cpp:18 -> sum2@src.cpp:2
0x61: src.cpp:18 -> sum2@src.cpp:2
0x66: src.cpp:18 -> sum2@src.cpp:2
0x67: src.cpp:18 -> sum2@src.cpp:2
0x69: src.cpp:18 -> sum2@src.cpp:2
0x6e: src.cpp:18 -> sum2@src.cpp:2
0x6f: src.cpp:18 -> sum2@src.cpp:2
0x71: src.cpp:18 -> sum2@src.cpp:2
0x76: src.cpp:18 -> sum2@src.cpp:2
0x77: src.cpp:18 -> sum2@src.cpp:2
0x79: src.cpp:18 -> sum2@src.cpp:2
0x7e: src.cpp:18 -> sum2@src.cpp:2
0x7f: src.cpp:19 -> sum4@src.cpp:12
0x81: src.cpp:19 -> sum4@src.cpp:12
0x86: src.cpp:19 -> sum4@src.cpp:12
0x87: src.cpp:19 -> sum4@src.cpp:12
0x89: src.cpp:19 -> sum4@src.cpp:12
0x8e: src.cpp:19 -> sum4@src.cpp:12 -> sum2@src.cpp:2
0x8f: src.cpp:19 -> sum4@src.cpp:12 -> sum2@src.cpp:2
0x91: src.cpp:19 -> sum4@src.cpp:12 -> sum2@src.cpp:2
0x96: src.cpp:19 -> sum4@src.cpp:12 -> sum2@src.cpp:3
0x97: src.cpp:19 -> sum4@src.cpp:12
0x99: src.cpp:19 -> sum4@src.cpp:12
0x9e: src.cpp:19 -> sum4@src.cpp:12
0x9f: src.cpp:19 -> sum4@src.cpp:12
0xa1: src.cpp:19 -> sum4@src.cpp:12
0xa6: src.cpp:19 -> sum4@src.cpp:12 -> sum2@src.cpp:2
0xa7: src.cpp:19 -> sum4@src.cpp:12 -> sum2@src.cpp:2
0xa9: src.cpp:19 -> sum4@src.cpp:12 -> sum2@src.cpp:2
0xae: src.cpp:19 -> sum4@src.cpp:12
0xaf: src.cpp:19 -> sum4@src.cpp:12
0xb1: src.cpp:19 -> sum4@src.cpp:12
0xb6: src.cpp:19 -> sum4@src.cpp:13
0xb7: src.cpp:19 -> sum4@src.cpp:13
0xb9: src.cpp:19 -> sum4@src.cpp:14
0xbe: src.cpp:19
0xbf: src.cpp:19
0xc1: src.cpp:19
0xc6: src.cpp:19
0xc7: src.cpp:19
0xc9: src.cpp:19
0xce: src.cpp:20 -> sum2@src.cpp:2
0xcf: src.cpp:20 -> sum2@src.cpp:2
0xd1: src.cpp:20 -> sum2@src.cpp:2
0xd6: src.cpp:21
0xd7: src.cpp:21
0xd9: src.cpp:21
0xde: src.cpp:21
*/
