"""
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"], debug_info=no_match(["pdb"]), 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",
        )

    @skipIfWasm  # there is no ABI plugin for Wasm to 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"
        )

    @skipIfWasm  # zero is a valid address in a Wasm linear memory, so a read of it succeeds
    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."""
        # 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.
        target, _, _, _ = lldbutil.run_to_line_breakpoint(
            self, lldb.SBFileSpec("main.c"), self.line1, exe_name=exe_name
        )

        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
    @skipIfWasm  # the default architecture is the host's, which no Wasm module matches
    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")
