"""
Test Debugger APIs.
"""

import lldb

from lldbsuite.test import lldbplatform
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil


class DebuggerAPITestCase(TestBase):
    NO_DEBUG_INFO_TESTCASE = True
    SHARED_BUILD_TESTCASE = False

    def test_debugger_api_boundary_condition(self):
        """Exercise SBDebugger APIs with boundary conditions."""
        self.dbg.HandleCommand(None)
        self.dbg.SetDefaultArchitecture(None)
        self.dbg.GetScriptingLanguage(None)
        self.dbg.CreateTarget(None)
        self.dbg.CreateTarget(None, None, None, True, lldb.SBError())
        self.dbg.CreateTargetWithFileAndTargetTriple(None, None)
        self.dbg.CreateTargetWithFileAndArch(None, None)
        self.dbg.FindTargetWithFileAndArch(None, None)
        self.dbg.SetInternalVariable(None, None, None)
        self.dbg.GetInternalVariableValue(None, None)
        # FIXME (filcab): We must first allow for the swig bindings to know if
        # a Python callback is set. (Check python-typemaps.swig)
        # self.dbg.SetLoggingCallback(None)
        self.dbg.SetPrompt(None)
        self.dbg.SetCurrentPlatform(None)
        self.dbg.SetCurrentPlatformSDKRoot(None)

        fresh_dbg = lldb.SBDebugger()
        self.assertEqual(len(fresh_dbg), 0)

    def test_debugger_delete_invalid_target(self):
        """SBDebugger.DeleteTarget() should not crash LLDB given and invalid target."""
        target = lldb.SBTarget()
        self.assertFalse(target.IsValid())
        self.dbg.DeleteTarget(target)

    def test_terminal_dimensions(self):
        """Test the SBDebugger terminal width/height accessors and the combined
        SetTerminalDimensions() setter."""
        # SetTerminalDimensions updates both axes at once.
        self.dbg.SetTerminalDimensions(143, 47)
        self.assertEqual(self.dbg.GetTerminalWidth(), 143)
        # Regression test: GetTerminalHeight() used to return the width.
        self.assertEqual(self.dbg.GetTerminalHeight(), 47)

        # The single-axis setters change only their own dimension and leave the
        # other one intact (they are implemented in terms of the combined call).
        self.dbg.SetTerminalWidth(99)
        self.assertEqual(self.dbg.GetTerminalWidth(), 99)
        self.assertEqual(self.dbg.GetTerminalHeight(), 47)

        self.dbg.SetTerminalHeight(31)
        self.assertEqual(self.dbg.GetTerminalWidth(), 99)
        self.assertEqual(self.dbg.GetTerminalHeight(), 31)

    def test_debugger_internal_variables(self):
        """Ensure that SBDebugger reachs the same instance of properties
        regardless CommandInterpreter's context initialization"""
        self.build()
        exe = self.getBuildArtifact("a.out")

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

        property_name = "target.process.memory-cache-line-size"

        def get_cache_line_size():
            value_list = lldb.SBStringList()
            value_list = self.dbg.GetInternalVariableValue(
                property_name, self.dbg.GetInstanceName()
            )

            self.assertEqual(value_list.GetSize(), 1)
            self.assertEqual(value_list[0], value_list.GetStringAtIndex(0))
            try:
                return int(value_list.GetStringAtIndex(0))
            except ValueError as error:
                self.fail("Value is not a number: " + error)

        # Get global property value while there are no processes.
        global_cache_line_size = get_cache_line_size()

        # Run a process via SB interface. CommandInterpreter's execution context
        # remains empty.
        error = lldb.SBError()
        launch_info = lldb.SBLaunchInfo(None)
        launch_info.SetLaunchFlags(lldb.eLaunchFlagStopAtEntry)
        process = target.Launch(launch_info, error)
        self.assertTrue(process, PROCESS_IS_VALID)

        # This should change the value of a process's local property.
        new_cache_line_size = global_cache_line_size + 512
        error = self.dbg.SetInternalVariable(
            property_name, str(new_cache_line_size), self.dbg.GetInstanceName()
        )
        self.assertSuccess(error, property_name + " value was changed successfully")

        # Check that it was set actually.
        self.assertEqual(get_cache_line_size(), new_cache_line_size)

        # Run any command to initialize CommandInterpreter's execution context.
        self.runCmd("target list")

        # Test the local property again, is it set to new_cache_line_size?
        self.assertEqual(get_cache_line_size(), new_cache_line_size)

    @expectedFailureAll(
        oslist=no_match(lldbplatform.translate(lldbplatform.darwin_all)),
        remote=True,
        bugnumber="github.com/llvm/llvm-project/issues/92419",
    )
    def test_CreateTarget_platform(self):
        exe = self.getBuildArtifact("a.out")
        self.yaml2obj("elf.yaml", exe)
        error = lldb.SBError()
        target1 = self.dbg.CreateTarget(exe, None, "remote-linux", False, error)
        self.assertSuccess(error)
        platform1 = target1.GetPlatform()
        platform1.SetWorkingDirectory("/foo/bar")

        # Reuse a platform if it matches the currently selected one...
        target2 = self.dbg.CreateTarget(exe, None, "remote-linux", False, error)
        self.assertSuccess(error)
        platform2 = target2.GetPlatform()
        self.assertTrue(
            platform2.GetWorkingDirectory().endswith("bar"),
            platform2.GetWorkingDirectory(),
        )

        # ... but create a new one if it doesn't.
        self.dbg.SetSelectedPlatform(lldb.SBPlatform("remote-windows"))
        target3 = self.dbg.CreateTarget(exe, None, "remote-linux", False, error)
        self.assertSuccess(error)
        platform3 = target3.GetPlatform()
        self.assertIsNone(platform3.GetWorkingDirectory())

    def test_CreateTarget_arch(self):
        exe = self.getBuildArtifact("a.out")
        if lldbplatformutil.getHostPlatform() == "linux":
            self.yaml2obj("macho.yaml", exe)
            arch = "x86_64-apple-macosx"
            expected_platform = "remote-macosx"
        else:
            self.yaml2obj("elf.yaml", exe)
            arch = "x86_64-pc-linux"
            expected_platform = "remote-linux"

        fbsd = lldb.SBPlatform("remote-freebsd")
        self.dbg.SetSelectedPlatform(fbsd)

        error = lldb.SBError()
        target1 = self.dbg.CreateTarget(exe, arch, None, False, error)
        self.assertSuccess(error)
        platform1 = target1.GetPlatform()
        self.assertEqual(platform1.GetName(), expected_platform)
        platform1.SetWorkingDirectory("/foo/bar")

        # Reuse a platform even if it is not currently selected.
        self.dbg.SetSelectedPlatform(fbsd)
        target2 = self.dbg.CreateTarget(exe, arch, None, False, error)
        self.assertSuccess(error)
        platform2 = target2.GetPlatform()
        self.assertEqual(platform2.GetName(), expected_platform)
        self.assertTrue(
            platform2.GetWorkingDirectory().endswith("bar"),
            platform2.GetWorkingDirectory(),
        )

    def test_SetDestroyCallback(self):
        destroy_dbg_id = None

        def foo(dbg_id):
            # Need nonlocal to modify closure variable.
            nonlocal destroy_dbg_id
            destroy_dbg_id = dbg_id

        self.dbg.SetDestroyCallback(foo)

        original_dbg_id = self.dbg.GetID()
        self.dbg.Destroy(self.dbg)
        self.assertEqual(destroy_dbg_id, original_dbg_id)

    def test_AddDestroyCallback(self):
        original_dbg_id = self.dbg.GetID()
        called = []

        def foo(dbg_id):
            # Need nonlocal to modify closure variable.
            nonlocal called
            called += [('foo', dbg_id)]

        def bar(dbg_id):
            # Need nonlocal to modify closure variable.
            nonlocal called
            called += [('bar', dbg_id)]

        token_foo = self.dbg.AddDestroyCallback(foo)
        token_bar = self.dbg.AddDestroyCallback(bar)
        self.dbg.Destroy(self.dbg)

        # Should call both `foo()` and `bar()`.
        self.assertEqual(called, [
            ('foo', original_dbg_id),
            ('bar', original_dbg_id),
        ])

    def test_RemoveDestroyCallback(self):
        original_dbg_id = self.dbg.GetID()
        called = []

        def foo(dbg_id):
            # Need nonlocal to modify closure variable.
            nonlocal called
            called += [('foo', dbg_id)]

        def bar(dbg_id):
            # Need nonlocal to modify closure variable.
            nonlocal called
            called += [('bar', dbg_id)]

        token_foo = self.dbg.AddDestroyCallback(foo)
        token_bar = self.dbg.AddDestroyCallback(bar)
        ret = self.dbg.RemoveDestroyCallback(token_foo)
        self.dbg.Destroy(self.dbg)

        # `Remove` should be successful
        self.assertTrue(ret)
        # Should only call `bar()`
        self.assertEqual(called, [('bar', original_dbg_id)])

    def test_RemoveDestroyCallback_invalid_token(self):
        original_dbg_id = self.dbg.GetID()
        magic_token_that_should_not_exist = 32413
        called = []

        def foo(dbg_id):
            # Need nonlocal to modify closure variable.
            nonlocal called
            called += [('foo', dbg_id)]

        token_foo = self.dbg.AddDestroyCallback(foo)
        ret = self.dbg.RemoveDestroyCallback(magic_token_that_should_not_exist)
        self.dbg.Destroy(self.dbg)

        # `Remove` should be unsuccessful
        self.assertFalse(ret)
        # Should call `foo()`
        self.assertEqual(called, [('foo', original_dbg_id)])

    def test_HandleDestroyCallback(self):
        """
        Validates:
        1. AddDestroyCallback and RemoveDestroyCallback work during debugger destroy.
        2. HandleDestroyCallback invokes all callbacks in FIFO order.
        """
        original_dbg_id = self.dbg.GetID()
        events = []
        bar_token = None

        def foo(dbg_id):
            # Need nonlocal to modify closure variable.
            nonlocal events
            events.append(('foo called', dbg_id))

        def bar(dbg_id):
            # Need nonlocal to modify closure variable.
            nonlocal events
            events.append(('bar called', dbg_id))

        def add_foo(dbg_id):
            # Need nonlocal to modify closure variable.
            nonlocal events
            events.append(('add_foo called', dbg_id))
            events.append(('foo token', self.dbg.AddDestroyCallback(foo)))

        def remove_bar(dbg_id):
            # Need nonlocal to modify closure variable.
            nonlocal events
            events.append(('remove_bar called', dbg_id))
            events.append(('remove bar ret', self.dbg.RemoveDestroyCallback(bar_token)))

        # Setup
        events.append(('add_foo token', self.dbg.AddDestroyCallback(add_foo)))
        bar_token = self.dbg.AddDestroyCallback(bar)
        events.append(('bar token', bar_token))
        events.append(('remove_bar token', self.dbg.AddDestroyCallback(remove_bar)))
        # Destroy
        self.dbg.Destroy(self.dbg)

        self.assertEqual(events, [
            # Setup
            ('add_foo token', 0), # add_foo should be added
            ('bar token', 1), # bar should be added
            ('remove_bar token', 2), # remove_bar should be added
            # Destroy
            ('add_foo called', original_dbg_id), # add_foo should be called
            ('foo token', 3), # foo should be added
            ('bar called', original_dbg_id), # bar should be called
            ('remove_bar called', original_dbg_id), # remove_bar should be called
            ('remove bar ret', False), # remove_bar should fail, because it's already invoked and removed
            ('foo called', original_dbg_id), # foo should be called
        ])

    def test_version(self):
        instance_str = self.dbg.GetVersionString()
        class_str = lldb.SBDebugger.GetVersionString()
        property_str = lldb.SBDebugger.version

        self.assertEqual(instance_str, class_str)
        self.assertEqual(class_str, property_str)

    def test_find_target_with_unique_id(self):
        """Test SBDebugger.FindTargetByGloballyUniqueID() functionality."""

        # Test with invalid ID - should return invalid target
        invalid_target = self.dbg.FindTargetByGloballyUniqueID(999999)
        self.assertFalse(invalid_target.IsValid())

        # Test with ID 0 - should return invalid target
        zero_target = self.dbg.FindTargetByGloballyUniqueID(0)
        self.assertFalse(zero_target.IsValid())

        # Build a real executable and create target with it
        self.build()
        exe = self.getBuildArtifact("a.out")
        target = self.dbg.CreateTarget(exe)
        self.assertTrue(target.IsValid())

        # Find the target using its unique ID
        unique_id = target.GetGloballyUniqueID()
        self.assertNotEqual(unique_id, lldb.LLDB_INVALID_GLOBALLY_UNIQUE_TARGET_ID)
        found_target = self.dbg.FindTargetByGloballyUniqueID(unique_id)
        self.assertTrue(found_target.IsValid())
        self.assertEqual(
            self.dbg.GetIndexOfTarget(target), self.dbg.GetIndexOfTarget(found_target)
        )
        self.assertEqual(found_target.GetGloballyUniqueID(), unique_id)

    def test_target_unique_id_uniqueness(self):
        """Test that Target.GetGloballyUniqueID() returns unique values across multiple targets."""

        # Create multiple targets and verify they all have unique IDs
        self.build()
        exe = self.getBuildArtifact("a.out")
        targets = []
        unique_ids = set()

        for i in range(10):
            target = self.dbg.CreateTarget(exe)
            self.assertTrue(target.IsValid())

            unique_id = target.GetGloballyUniqueID()
            self.assertNotEqual(unique_id, 0)

            # Verify this ID hasn't been used before
            self.assertNotIn(
                unique_id, unique_ids, f"Duplicate unique ID found: {unique_id}"
            )

            unique_ids.add(unique_id)
            targets.append(target)

        # Verify all targets can still be found by their IDs
        for target in targets:
            unique_id = target.GetGloballyUniqueID()
            found = self.dbg.FindTargetByGloballyUniqueID(unique_id)
            self.assertTrue(found.IsValid())
            self.assertEqual(found.GetGloballyUniqueID(), unique_id)

    def test_target_unique_id_uniqueness_after_deletion(self):
        """Test finding targets have unique ID after target deletion."""
        # Create two targets
        self.build()
        exe = self.getBuildArtifact("a.out")
        target1 = self.dbg.CreateTarget(exe)
        target2 = self.dbg.CreateTarget(exe)
        self.assertTrue(target1.IsValid())
        self.assertTrue(target2.IsValid())

        unique_id1 = target1.GetGloballyUniqueID()
        unique_id2 = target2.GetGloballyUniqueID()
        self.assertNotEqual(unique_id1, 0)
        self.assertNotEqual(unique_id2, 0)
        self.assertNotEqual(unique_id1, unique_id2)

        # Verify we can find them initially
        found_target1 = self.dbg.FindTargetByGloballyUniqueID(unique_id1)
        found_target2 = self.dbg.FindTargetByGloballyUniqueID(unique_id2)
        self.assertTrue(found_target1.IsValid())
        self.assertTrue(found_target2.IsValid())
        target2_index = self.dbg.GetIndexOfTarget(target2)

        # Delete target 2
        deleted = self.dbg.DeleteTarget(target2)
        self.assertTrue(deleted)

        # Try to find the deleted target - should not be found
        not_found_target = self.dbg.FindTargetByGloballyUniqueID(unique_id2)
        self.assertFalse(not_found_target.IsValid())

        # Create a new target
        target3 = self.dbg.CreateTarget(exe)
        self.assertTrue(target3.IsValid())
        # Target list index of target3 should be the same as target2's
        # since it was deleted, but it should have a distinct unique ID
        target3_index = self.dbg.GetIndexOfTarget(target3)
        unique_id3 = target3.GetGloballyUniqueID()
        self.assertEqual(target3_index, target2_index)
        self.assertNotEqual(unique_id3, unique_id2)
        self.assertNotEqual(unique_id3, unique_id1)
        # Make sure we can find the new target
        found_target3 = self.dbg.FindTargetByGloballyUniqueID(
            target3.GetGloballyUniqueID()
        )
        self.assertTrue(found_target3.IsValid())

    def test_target_globally_unique_id_across_debuggers(self):
        """Test that target IDs are globally unique across multiple debuggers."""
        self.build()
        exe = self.getBuildArtifact("a.out")

        # Create two debuggers with targets each
        debugger1 = lldb.SBDebugger.Create()
        debugger2 = lldb.SBDebugger.Create()
        self.addTearDownHook(lambda: lldb.SBDebugger.Destroy(debugger1))
        self.addTearDownHook(lambda: lldb.SBDebugger.Destroy(debugger2))

        # Create 2 targets per debugger
        targets_d1 = [debugger1.CreateTarget(exe), debugger1.CreateTarget(exe)]
        targets_d2 = [debugger2.CreateTarget(exe), debugger2.CreateTarget(exe)]
        targets = targets_d1 + targets_d2

        # Get all IDs and verify they're unique
        ids = [target.GetGloballyUniqueID() for target in targets]
        self.assertEqual(
            len(set(ids)), len(ids), f"IDs should be globally unique: {ids}"
        )
        self.assertTrue(
            all(uid != lldb.LLDB_INVALID_GLOBALLY_UNIQUE_TARGET_ID for uid in ids),
            "All IDs should be valid",
        )

        # Verify targets can be found by their IDs in respective debuggers
        for debugger, target_pair in [
            (debugger1, targets[:2]),
            (debugger2, targets[2:]),
        ]:
            for target in target_pair:
                found = debugger.FindTargetByGloballyUniqueID(
                    target.GetGloballyUniqueID()
                )
                self.assertTrue(
                    found.IsValid(), "Target should be found by its unique ID"
                )
                self.assertEqual(
                    found.GetGloballyUniqueID(), target.GetGloballyUniqueID()
                )
