"""
Test Debugger APIs.
"""

import lldb

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


class DebuggerAPITestCase(TestBase):
    NO_DEBUG_INFO_TESTCASE = True

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