"""
Test some SBModule and SBSection APIs.
"""

import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
from lldbsuite.test.lldbutil import symbol_type_to_str


class ModuleAndSectionAPIsTestCase(TestBase):
    SHARED_BUILD_TESTCASE = False

    def test_module_and_section(self):
        """Test module and section APIs."""
        self.build()
        exe = self.getBuildArtifact("a.out")

        target = self.dbg.CreateTarget(exe)
        self.assertTrue(target, VALID_TARGET)
        self.assertGreater(target.GetNumModules(), 0)

        # Hide stdout if not running with '-t' option.
        if not self.TraceOn():
            self.HideStdout()

        print("Number of modules for the target: %d" % target.GetNumModules())
        for module in target.module_iter():
            print(module)

        # Get the executable module at index 0.
        exe_module = target.GetModuleAtIndex(0)

        print("Exe module: %s" % str(exe_module))
        print("Number of sections: %d" % exe_module.GetNumSections())
        print("Number of symbols: %d" % len(exe_module))
        INDENT = " " * 4
        INDENT2 = INDENT * 2
        for sec in exe_module.section_iter():
            print(sec)
            print(INDENT + "Number of subsections: %d" % sec.GetNumSubSections())
            if sec.GetNumSubSections() == 0:
                for sym in exe_module.symbol_in_section_iter(sec):
                    print(INDENT + str(sym))
                    print(
                        INDENT + "symbol type: %s" % symbol_type_to_str(sym.GetType())
                    )
            else:
                for subsec in sec:
                    print(INDENT + str(subsec))
                    # Now print the symbols belonging to the subsection....
                    for sym in exe_module.symbol_in_section_iter(subsec):
                        print(INDENT2 + str(sym))
                        print(
                            INDENT2
                            + "symbol type: %s" % symbol_type_to_str(sym.GetType())
                        )

    def test_module_and_section_boundary_condition(self):
        """Test module and section APIs by passing None when it expects a Python string."""
        self.build()
        exe = self.getBuildArtifact("a.out")

        target = self.dbg.CreateTarget(exe)
        self.assertTrue(target, VALID_TARGET)
        self.assertGreater(target.GetNumModules(), 0)

        # Hide stdout if not running with '-t' option.
        if not self.TraceOn():
            self.HideStdout()

        print("Number of modules for the target: %d" % target.GetNumModules())
        for module in target.module_iter():
            print(module)

        # Get the executable module at index 0.
        exe_module = target.GetModuleAtIndex(0)

        print("Exe module: %s" % str(exe_module))
        print("Number of sections: %d" % exe_module.GetNumSections())

        # Boundary condition testings.  Should not crash lldb!
        exe_module.FindFirstType(None)
        exe_module.FindTypes(None)
        exe_module.FindGlobalVariables(target, None, 1)
        exe_module.FindFunctions(None, 0)
        exe_module.FindSection(None)

        # Get the section at index 1.
        if exe_module.GetNumSections() > 1:
            sec1 = exe_module.GetSectionAtIndex(1)
            print(sec1)
        else:
            sec1 = None

        if sec1:
            sec1.FindSubSection(None)

    def test_module_compile_unit_iter(self):
        """Test module's compile unit iterator APIs."""
        self.build()
        exe = self.getBuildArtifact("a.out")

        target = self.dbg.CreateTarget(exe)
        self.assertTrue(target, VALID_TARGET)
        self.assertGreater(target.GetNumModules(), 0)

        # Hide stdout if not running with '-t' option.
        if not self.TraceOn():
            self.HideStdout()

        print("Number of modules for the target: %d" % target.GetNumModules())
        for module in target.module_iter():
            print(module)

        # Get the executable module at index 0.
        exe_module = target.GetModuleAtIndex(0)

        print("Exe module: %s" % str(exe_module))
        print("Number of compile units: %d" % exe_module.GetNumCompileUnits())
        INDENT = " " * 4
        INDENT2 = INDENT * 2
        for cu in exe_module.compile_unit_iter():
            print(cu)

    def test_find_compile_units(self):
        """Exercise SBModule.FindCompileUnits() API."""
        d = {"EXE": "b.out"}
        self.build(dictionary=d)
        self.setTearDownCleanup(dictionary=d)
        self.find_compile_units(self.getBuildArtifact("b.out"))

    def find_compile_units(self, exe):
        """Exercise SBModule.FindCompileUnits() API."""
        source_name_list = ["main.cpp", "b.cpp", "c.cpp"]

        # Create a target by the debugger.
        target = self.dbg.CreateTarget(exe)
        self.assertTrue(target, VALID_TARGET)

        num_modules = target.GetNumModules()
        for i in range(num_modules):
            module = target.GetModuleAtIndex(i)
            for source_name in source_name_list:
                list = module.FindCompileUnits(lldb.SBFileSpec(source_name, False))
                for sc in list:
                    self.assertEqual(
                        sc.GetCompileUnit().GetFileSpec().GetFilename(), source_name
                    )
