"""
Test SBTarget APIs.
"""

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


class TargetAPITestCase(TestBase):
    SHARED_BUILD_TESTCASE = False

    def setUp(self):
        # Call super's setUp().
        TestBase.setUp(self)
        # Find the line number to of function 'c'.
        self.line1 = line_number(
            "main.c", "// Find the line number for breakpoint 1 here."
        )
        self.line2 = line_number(
            "main.c", "// Find the line number for breakpoint 2 here."
        )
        self.line_main = line_number("main.c", "// Set a break at entry to main.")

    # rdar://problem/9700873
    # Find global variable value fails for dwarf if inferior not started
    # (Was CrashTracer: [USER] 1 crash in Python at _lldb.so: lldb_private::MemoryCache::Read + 94)
    #
    # It does not segfaults now.  But for dwarf, the variable value is None if
    # the inferior process does not exist yet.  The radar has been updated.
    def test_find_global_variables(self):
        """Exercise SBTarget.FindGlobalVariables() API."""
        d = {"EXE": "b.out"}
        self.build(dictionary=d)
        self.setTearDownCleanup(dictionary=d)
        self.find_global_variables("b.out")

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

    @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24778")
    def test_find_functions(self):
        """Exercise SBTarget.FindFunctions() API."""
        d = {"EXE": "b.out"}
        self.build(dictionary=d)
        self.setTearDownCleanup(dictionary=d)
        self.find_functions("b.out")

    def test_get_description(self):
        """Exercise SBTarget.GetDescription() API."""
        self.build()
        self.get_description()

    @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr21765")
    def test_resolve_symbol_context_with_address(self):
        """Exercise SBTarget.ResolveSymbolContextForAddress() API."""
        self.build()
        self.resolve_symbol_context_with_address()

    def test_get_platform(self):
        d = {"EXE": "b.out"}
        self.build(dictionary=d)
        self.setTearDownCleanup(dictionary=d)
        target = self.create_simple_target("b.out")
        platform = target.platform
        self.assertTrue(platform, VALID_PLATFORM)

    def test_resolve_file_address(self):
        d = {"EXE": "b.out"}
        self.build(dictionary=d)
        self.setTearDownCleanup(dictionary=d)
        target = self.create_simple_target("b.out")

        # find the file address in the .data section of the main
        # module
        data_section = self.find_data_section(target)
        data_section_addr = data_section.file_addr

        # resolve the above address, and compare the address produced
        # by the resolution against the original address/section
        res_file_addr = target.ResolveFileAddress(data_section_addr)
        self.assertTrue(res_file_addr.IsValid())

        self.assertEqual(data_section_addr, res_file_addr.file_addr)

        data_section2 = res_file_addr.section
        self.assertIsNotNone(data_section2)
        self.assertEqual(data_section.name, data_section2.name)

    def test_get_arch_name(self):
        d = {"EXE": "b.out"}
        self.build(dictionary=d)
        self.setTearDownCleanup(dictionary=d)
        target = self.create_simple_target("b.out")

        arch_name = target.arch_name
        self.assertTrue(len(arch_name) > 0, "Got an arch name")

        # Test consistency with triple.
        triple = target.triple
        self.assertTrue(len(triple) > 0, "Got a triple")
        self.assertEqual(
            triple.split("-")[0],
            arch_name,
            "Arch name is equal to the first item of the triple",
        )

    def test_get_ABIName(self):
        d = {"EXE": "b.out"}
        self.build(dictionary=d)
        self.setTearDownCleanup(dictionary=d)
        target = self.create_simple_target("b.out")

        abi_pre_launch = target.GetABIName()
        self.assertNotEqual(len(abi_pre_launch), 0, "Got an ABI string")

        breakpoint = target.BreakpointCreateByLocation("main.c", self.line_main)
        self.assertTrue(breakpoint, VALID_BREAKPOINT)

        # Put debugger into synchronous mode so when we target.LaunchSimple returns
        # it will guaranteed to be at the breakpoint
        self.dbg.SetAsync(False)

        # Launch the process, and do not stop at the entry point.
        process = target.LaunchSimple(None, None, self.get_process_working_directory())
        abi_after_launch = target.GetABIName()
        self.assertEqual(
            abi_pre_launch, abi_after_launch, "ABI's match before and during run"
        )

    def test_read_memory(self):
        d = {"EXE": "b.out"}
        self.build(dictionary=d)
        self.setTearDownCleanup(dictionary=d)
        target = self.create_simple_target("b.out")

        breakpoint = target.BreakpointCreateByLocation("main.c", self.line_main)
        self.assertTrue(breakpoint, VALID_BREAKPOINT)

        # Put debugger into synchronous mode so when we target.LaunchSimple returns
        # it will guaranteed to be at the breakpoint
        self.dbg.SetAsync(False)

        # Launch the process, and do not stop at the entry point.
        process = target.LaunchSimple(None, None, self.get_process_working_directory())

        # find the file address in the .data section of the main
        # module
        data_section = self.find_data_section(target)
        sb_addr = lldb.SBAddress(data_section, 0)
        error = lldb.SBError()
        content = target.ReadMemory(sb_addr, 1, error)
        self.assertSuccess(error, "Make sure memory read succeeded")
        self.assertEqual(len(content), 1)

        # Make sure reading from 0x0 fails
        sb_addr = lldb.SBAddress(0, target)
        self.assertIsNone(target.ReadMemory(sb_addr, 1, error))
        self.assertTrue(error.Fail())

    @skipIfWindows  # stdio manipulation unsupported on Windows
    @skipIfRemote  # stdio manipulation unsupported on remote iOS devices<rdar://problem/54581135>
    @skipIf(oslist=["linux"], archs=["arm$", "aarch64"])
    @no_debug_info_test
    def test_launch_simple(self):
        d = {"EXE": "b.out"}
        self.build(dictionary=d)
        self.setTearDownCleanup(dictionary=d)
        target = self.create_simple_target("b.out")

        # Set the debugger to synchronous mode so we only continue after the
        # process has exited.
        self.dbg.SetAsync(False)

        process = target.LaunchSimple(
            ["foo", "bar"], ["baz"], self.get_process_working_directory()
        )
        process.Continue()
        self.assertState(process.GetState(), lldb.eStateExited)
        output = process.GetSTDOUT(9999)
        self.assertIn("arg: foo", output)
        self.assertIn("arg: bar", output)
        self.assertIn("env: baz", output)

        self.runCmd("setting set target.run-args foo")
        self.runCmd("setting set target.env-vars bar=baz")
        process = target.LaunchSimple(None, None, self.get_process_working_directory())
        process.Continue()
        self.assertState(process.GetState(), lldb.eStateExited)
        output = process.GetSTDOUT(9999)
        self.assertIn("arg: foo", output)
        self.assertIn("env: bar=baz", output)

        # Clear all the run args set above.
        self.runCmd("setting clear target.run-args")
        process = target.LaunchSimple(None, None, self.get_process_working_directory())
        process.Continue()
        self.assertEqual(process.GetState(), lldb.eStateExited)
        output = process.GetSTDOUT(9999)
        self.assertNotIn("arg: foo", output)

        self.runCmd("settings set target.disable-stdio true")
        process = target.LaunchSimple(None, None, self.get_process_working_directory())
        process.Continue()
        self.assertState(process.GetState(), lldb.eStateExited)
        output = process.GetSTDOUT(9999)
        self.assertEqual(output, "")

    def create_simple_target(self, fn):
        exe = self.getBuildArtifact(fn)
        target = self.dbg.CreateTarget(exe)
        self.assertTrue(target, VALID_TARGET)
        return target

    def find_data_section(self, target):
        mod = target.GetModuleAtIndex(0)
        data_section = None
        for s in mod.sections:
            sect_type = s.GetSectionType()
            if sect_type == lldb.eSectionTypeData:
                data_section = s
                break
            elif sect_type == lldb.eSectionTypeContainer:
                for i in range(s.GetNumSubSections()):
                    ss = s.GetSubSectionAtIndex(i)
                    sect_type = ss.GetSectionType()
                    if sect_type == lldb.eSectionTypeData:
                        data_section = ss
                        break

        self.assertIsNotNone(data_section)
        return data_section

    def find_global_variables(self, exe_name):
        """Exercise SBTarget.FindGlobalVariables() API."""
        exe = self.getBuildArtifact(exe_name)

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

        # rdar://problem/9700873
        # Find global variable value fails for dwarf if inferior not started
        # (Was CrashTracer: [USER] 1 crash in Python at _lldb.so: lldb_private::MemoryCache::Read + 94)
        #
        # Remove the lines to create a breakpoint and to start the inferior
        # which are workarounds for the dwarf case.

        breakpoint = target.BreakpointCreateByLocation("main.c", self.line1)
        self.assertTrue(breakpoint, VALID_BREAKPOINT)

        # Now launch the process, and do not stop at entry point.
        process = target.LaunchSimple(None, None, self.get_process_working_directory())
        self.assertTrue(process, PROCESS_IS_VALID)
        # Make sure we hit our breakpoint:
        thread_list = lldbutil.get_threads_stopped_at_breakpoint(process, breakpoint)
        self.assertEqual(len(thread_list), 1)

        value_list = target.FindGlobalVariables("my_global_var_of_char_type", 3)
        self.assertEqual(value_list.GetSize(), 1)
        my_global_var = value_list.GetValueAtIndex(0)
        self.DebugSBValue(my_global_var)
        self.assertTrue(my_global_var)
        self.expect(
            my_global_var.GetName(), exe=False, startstr="my_global_var_of_char_type"
        )
        self.expect(my_global_var.GetTypeName(), exe=False, startstr="char")
        self.expect(my_global_var.GetValue(), exe=False, startstr="'X'")

        # While we are at it, let's also exercise the similar
        # SBModule.FindGlobalVariables() API.
        for m in target.module_iter():
            if (
                os.path.normpath(m.GetFileSpec().GetDirectory()) == self.getBuildDir()
                and m.GetFileSpec().GetFilename() == exe_name
            ):
                value_list = m.FindGlobalVariables(
                    target, "my_global_var_of_char_type", 3
                )
                self.assertEqual(value_list.GetSize(), 1)
                self.assertEqual(value_list.GetValueAtIndex(0).GetValue(), "'X'")
                break

    def find_compile_units(self, exe):
        """Exercise SBTarget.FindCompileUnits() API."""
        source_name = "main.c"

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

        list = target.FindCompileUnits(lldb.SBFileSpec(source_name, False))
        # Executable has been built just from one source file 'main.c',
        # so we may check only the first element of list.
        self.assertEqual(
            list[0].GetCompileUnit().GetFileSpec().GetFilename(), source_name
        )

    def find_functions(self, exe_name):
        """Exercise SBTarget.FindFunctions() API."""
        exe = self.getBuildArtifact(exe_name)

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

        # Try it with a null name:
        list = target.FindFunctions(None, lldb.eFunctionNameTypeAuto)
        self.assertEqual(list.GetSize(), 0)

        list = target.FindFunctions("c", lldb.eFunctionNameTypeAuto)
        self.assertEqual(list.GetSize(), 1)

        for sc in list:
            self.assertEqual(sc.GetModule().GetFileSpec().GetFilename(), exe_name)
            self.assertEqual(sc.GetSymbol().GetName(), "c")

    def get_description(self):
        """Exercise SBTarget.GetDescription() API."""
        exe = self.getBuildArtifact("a.out")

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

        from lldbsuite.test.lldbutil import get_description

        # get_description() allows no option to mean
        # lldb.eDescriptionLevelBrief.
        desc = get_description(target)
        # desc = get_description(target, option=lldb.eDescriptionLevelBrief)
        if not desc:
            self.fail("SBTarget.GetDescription() failed")
        self.expect(desc, exe=False, substrs=["a.out"])
        self.expect(
            desc, exe=False, matching=False, substrs=["Target", "Module", "Breakpoint"]
        )

        desc = get_description(target, option=lldb.eDescriptionLevelFull)
        if not desc:
            self.fail("SBTarget.GetDescription() failed")
        self.expect(
            desc, exe=False, substrs=["Target", "Module", "a.out", "Breakpoint"]
        )

    @skipIfRemote
    @no_debug_info_test
    def test_launch_new_process_and_redirect_stdout(self):
        """Exercise SBTarget.Launch() API with redirected stdout."""
        self.build()
        exe = self.getBuildArtifact("a.out")

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

        # Add an extra twist of stopping the inferior in a breakpoint, and then continue till it's done.
        # We should still see the entire stdout redirected once the process is
        # finished.
        line = line_number("main.c", "// a(3) -> c(3)")
        breakpoint = target.BreakpointCreateByLocation("main.c", line)

        # Now launch the process, do not stop at entry point, and redirect stdout to "stdout.txt" file.
        # The inferior should run to completion after "process.Continue()"
        # call.
        local_path = self.getBuildArtifact("stdout.txt")
        if os.path.exists(local_path):
            os.remove(local_path)

        if lldb.remote_platform:
            stdout_path = lldbutil.append_to_process_working_directory(
                self, "lldb-stdout-redirect.txt"
            )
        else:
            stdout_path = local_path
        error = lldb.SBError()
        process = target.Launch(
            self.dbg.GetListener(),
            None,
            None,
            None,
            stdout_path,
            None,
            None,
            0,
            False,
            error,
        )
        process.Continue()
        # self.runCmd("process status")
        if lldb.remote_platform:
            # copy output file to host
            lldb.remote_platform.Get(
                lldb.SBFileSpec(stdout_path), lldb.SBFileSpec(local_path)
            )

        # The 'stdout.txt' file should now exist.
        self.assertTrue(
            os.path.isfile(local_path),
            "'stdout.txt' exists due to redirected stdout via SBTarget.Launch() API.",
        )

        # Read the output file produced by running the program.
        with open(local_path, "r") as f:
            output = f.read()

        self.expect(output, exe=False, substrs=["a(1)", "b(2)", "a(3)"])

    def resolve_symbol_context_with_address(self):
        """Exercise SBTarget.ResolveSymbolContextForAddress() API."""
        exe = self.getBuildArtifact("a.out")

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

        # Now create the two breakpoints inside function 'a'.
        breakpoint1 = target.BreakpointCreateByLocation("main.c", self.line1)
        breakpoint2 = target.BreakpointCreateByLocation("main.c", self.line2)
        self.trace("breakpoint1:", breakpoint1)
        self.trace("breakpoint2:", breakpoint2)
        self.assertTrue(
            breakpoint1 and breakpoint1.GetNumLocations() == 1, VALID_BREAKPOINT
        )
        self.assertTrue(
            breakpoint2 and breakpoint2.GetNumLocations() == 1, VALID_BREAKPOINT
        )

        # Now launch the process, and do not stop at entry point.
        process = target.LaunchSimple(None, None, self.get_process_working_directory())
        self.assertTrue(process, PROCESS_IS_VALID)

        # Frame #0 should be on self.line1.
        self.assertState(process.GetState(), lldb.eStateStopped)
        thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint)
        self.assertTrue(
            thread.IsValid(),
            "There should be a thread stopped due to breakpoint condition",
        )
        # self.runCmd("process status")
        frame0 = thread.GetFrameAtIndex(0)
        lineEntry = frame0.GetLineEntry()
        self.assertEqual(lineEntry.GetLine(), self.line1)

        address1 = lineEntry.GetStartAddress()

        # Continue the inferior, the breakpoint 2 should be hit.
        process.Continue()
        self.assertState(process.GetState(), lldb.eStateStopped)
        thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint)
        self.assertTrue(
            thread.IsValid(),
            "There should be a thread stopped due to breakpoint condition",
        )
        # self.runCmd("process status")
        frame0 = thread.GetFrameAtIndex(0)
        lineEntry = frame0.GetLineEntry()
        self.assertEqual(lineEntry.GetLine(), self.line2)

        address2 = lineEntry.GetStartAddress()

        self.trace("address1:", address1)
        self.trace("address2:", address2)

        # Now call SBTarget.ResolveSymbolContextForAddress() with the addresses
        # from our line entry.
        context1 = target.ResolveSymbolContextForAddress(
            address1, lldb.eSymbolContextEverything
        )
        context2 = target.ResolveSymbolContextForAddress(
            address2, lldb.eSymbolContextEverything
        )

        self.assertTrue(context1 and context2)
        self.trace("context1:", context1)
        self.trace("context2:", context2)

        # Verify that the context point to the same function 'a'.
        symbol1 = context1.GetSymbol()
        symbol2 = context2.GetSymbol()
        self.assertTrue(symbol1 and symbol2)
        self.trace("symbol1:", symbol1)
        self.trace("symbol2:", symbol2)

        from lldbsuite.test.lldbutil import get_description

        desc1 = get_description(symbol1)
        desc2 = get_description(symbol2)
        self.assertTrue(
            desc1 and desc2 and desc1 == desc2,
            "The two addresses should resolve to the same symbol",
        )

    @skipIfRemote
    def test_default_arch(self):
        """Test the other two target create methods using LLDB_ARCH_DEFAULT."""
        self.build()
        exe = self.getBuildArtifact("a.out")
        target = self.dbg.CreateTargetWithFileAndArch(exe, lldb.LLDB_ARCH_DEFAULT)
        self.assertTrue(target.IsValid(), "Default arch made a valid target.")
        # This should also work with the target's triple:
        target2 = self.dbg.CreateTargetWithFileAndArch(exe, target.GetTriple())
        self.assertTrue(target2.IsValid(), "Round trip with triple works")
        # And this triple should work for the FileAndTriple API:
        target3 = self.dbg.CreateTargetWithFileAndTargetTriple(exe, target.GetTriple())
        self.assertTrue(target3.IsValid())

    @skipIfWindows
    def test_is_loaded(self):
        """Exercise SBTarget.IsLoaded(SBModule&) API."""
        d = {"EXE": "b.out"}
        self.build(dictionary=d)
        self.setTearDownCleanup(dictionary=d)
        target = self.create_simple_target("b.out")

        self.assertFalse(target.IsLoaded(lldb.SBModule()))

        num_modules = target.GetNumModules()
        for i in range(num_modules):
            module = target.GetModuleAtIndex(i)
            self.assertFalse(
                target.IsLoaded(module),
                "Target that isn't " "running shouldn't have any module loaded.",
            )

        process = target.LaunchSimple(None, None, self.get_process_working_directory())

        for i in range(num_modules):
            module = target.GetModuleAtIndex(i)
            self.assertTrue(
                target.IsLoaded(module),
                "Running the target should " "have loaded its modules.",
            )

    @no_debug_info_test
    def test_setting_selected_target_with_invalid_target(self):
        """Make sure we don't crash when trying to select invalid target."""
        target = lldb.SBTarget()
        self.dbg.SetSelectedTarget(target)

    @no_debug_info_test
    def test_get_api_mutex(self):
        """Make sure we can lock and unlock the API mutex from Python."""
        target = self.dbg.GetDummyTarget()

        mutex = target.GetAPIMutex()
        self.assertTrue(mutex.IsValid())
        mutex.lock()
        # The API call below doesn't actually matter, it's just there to
        # confirm we don't block on the API lock.
        target.BreakpointCreateByName("foo", "bar")
        mutex.unlock()

    @no_debug_info_test
    def test_get_api_mutex_with_statement(self):
        """Make sure we can lock and unlock the API mutex using a with-statement from Python."""
        target = self.dbg.GetDummyTarget()

        with target.GetAPIMutex() as mutex:
            self.assertTrue(mutex.IsValid())
            # The API call below doesn't actually matter, it's just there to
            # confirm we don't block on the API lock.
            target.BreakpointCreateByName("foo", "bar")
