"""
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):
    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_get_data_byte_size(self):
        d = {"EXE": "b.out"}
        self.build(dictionary=d)
        self.setTearDownCleanup(dictionary=d)
        target = self.create_simple_target("b.out")
        self.assertEqual(target.data_byte_size, 1)

    def test_get_code_byte_size(self):
        d = {"EXE": "b.out"}
        self.build(dictionary=d)
        self.setTearDownCleanup(dictionary=d)
        target = self.create_simple_target("b.out")
        self.assertEqual(target.code_byte_size, 1)

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