"""
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):
    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
                    )
