"""
Test setting breakpoints using a scripted resolver
"""

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


class TestScriptedResolver(TestBase):
    NO_DEBUG_INFO_TESTCASE = True

    @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24528")
    def test_scripted_resolver(self):
        """Use a scripted resolver to set a by symbol name breakpoint"""
        self.build()
        self.do_test()

    @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24528")
    def test_search_depths(self):
        """Make sure we are called at the right depths depending on what we return
        from __get_depth__"""
        self.build()
        self.do_test_depths()

    @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24528")
    def test_command_line(self):
        """Test setting a resolver breakpoint from the command line"""
        self.build()
        self.do_test_cli()

    def test_bad_command_lines(self):
        """Make sure we get appropriate errors when we give invalid key/value
        options"""
        self.build()
        self.do_test_bad_options()

    def test_copy_from_dummy_target(self):
        """Make sure we don't crash during scripted breakpoint copy from dummy target"""
        self.build()
        self.do_test_copy_from_dummy_target()

    def make_target_and_import(self):
        target = self.make_target()
        self.import_resolver_script()
        return target

    def make_target(self):
        return lldbutil.run_to_breakpoint_make_target(self)

    def import_resolver_script(self):
        interp = self.dbg.GetCommandInterpreter()
        error = lldb.SBError()

        script_name = os.path.join(self.getSourceDir(), "resolver.py")
        source_name = os.path.join(self.getSourceDir(), "main.c")

        command = "command script import " + script_name
        result = lldb.SBCommandReturnObject()
        interp.HandleCommand(command, result)
        self.assertTrue(
            result.Succeeded(), "com scr imp failed: %s" % (result.GetError())
        )

    def make_extra_args(self):
        json_string = '{"symbol":"break_on_me", "test1": "value1"}'
        json_stream = lldb.SBStream()
        json_stream.Print(json_string)
        extra_args = lldb.SBStructuredData()
        error = extra_args.SetFromJSON(json_stream)
        self.assertSuccess(error, "Error making SBStructuredData")
        return extra_args

    def do_test(self):
        """This reads in a python file and sets a breakpoint using it."""

        target = self.make_target_and_import()
        extra_args = self.make_extra_args()

        file_list = lldb.SBFileSpecList()
        module_list = lldb.SBFileSpecList()

        # Make breakpoints with this resolver using different filters, first ones that will take:
        right = []
        # one with no file or module spec - this one should fire:
        right.append(
            target.BreakpointCreateFromScript(
                "resolver.Resolver", extra_args, module_list, file_list
            )
        )

        # one with the right source file and no module - should also fire:
        file_list.Append(lldb.SBFileSpec("main.c"))
        right.append(
            target.BreakpointCreateFromScript(
                "resolver.Resolver", extra_args, module_list, file_list
            )
        )
        # Make sure the help text shows up in the "break list" output:
        self.expect(
            "break list",
            substrs=["I am a python breakpoint resolver"],
            msg="Help is listed in break list",
        )

        # one with the right source file and right module - should also fire:
        module_list.Append(lldb.SBFileSpec("a.out"))
        right.append(
            target.BreakpointCreateFromScript(
                "resolver.Resolver", extra_args, module_list, file_list
            )
        )

        # And one with no source file but the right module:
        file_list.Clear()
        right.append(
            target.BreakpointCreateFromScript(
                "resolver.Resolver", extra_args, module_list, file_list
            )
        )

        # Make sure these all got locations:
        for i in range(0, len(right)):
            self.assertGreaterEqual(
                right[i].GetNumLocations(), 1, "Breakpoint %d has no locations." % (i)
            )

        # Now some ones that won't take:

        module_list.Clear()
        file_list.Clear()
        wrong = []

        # one with the wrong module - should not fire:
        module_list.Append(lldb.SBFileSpec("noSuchModule"))
        wrong.append(
            target.BreakpointCreateFromScript(
                "resolver.Resolver", extra_args, module_list, file_list
            )
        )

        # one with the wrong file - also should not fire:
        file_list.Clear()
        module_list.Clear()
        file_list.Append(lldb.SBFileSpec("noFileOfThisName.xxx"))
        wrong.append(
            target.BreakpointCreateFromScript(
                "resolver.Resolver", extra_args, module_list, file_list
            )
        )

        # Now make sure the CU level iteration obeys the file filters:
        file_list.Clear()
        module_list.Clear()
        file_list.Append(lldb.SBFileSpec("no_such_file.xxx"))
        wrong.append(
            target.BreakpointCreateFromScript(
                "resolver.ResolverCUDepth", extra_args, module_list, file_list
            )
        )

        # And the Module filters:
        file_list.Clear()
        module_list.Clear()
        module_list.Append(lldb.SBFileSpec("NoSuchModule.dylib"))
        wrong.append(
            target.BreakpointCreateFromScript(
                "resolver.ResolverCUDepth", extra_args, module_list, file_list
            )
        )

        # Now make sure the Function level iteration obeys the file filters:
        file_list.Clear()
        module_list.Clear()
        file_list.Append(lldb.SBFileSpec("no_such_file.xxx"))
        wrong.append(
            target.BreakpointCreateFromScript(
                "resolver.ResolverFuncDepth", extra_args, module_list, file_list
            )
        )

        # And the Module filters:
        file_list.Clear()
        module_list.Clear()
        module_list.Append(lldb.SBFileSpec("NoSuchModule.dylib"))
        wrong.append(
            target.BreakpointCreateFromScript(
                "resolver.ResolverFuncDepth", extra_args, module_list, file_list
            )
        )

        # Make sure these didn't get locations:
        for i in range(0, len(wrong)):
            self.assertEqual(
                wrong[i].GetNumLocations(), 0, "Breakpoint %d has locations." % (i)
            )

        # Now run to main and ensure we hit the breakpoints we should have:

        lldbutil.run_to_breakpoint_do_run(self, target, right[0])

        # Test the hit counts:
        for i in range(0, len(right)):
            self.assertEqual(
                right[i].GetHitCount(), 1, "Breakpoint %d has the wrong hit count" % (i)
            )

        for i in range(0, len(wrong)):
            self.assertEqual(
                wrong[i].GetHitCount(), 0, "Breakpoint %d has the wrong hit count" % (i)
            )

    def do_test_depths(self):
        """This test uses a class variable in resolver.Resolver which gets set to 1 if we saw
        compile unit and 2 if we only saw modules.  If the search depth is module, you get passed just
        the modules with no comp_unit.  If the depth is comp_unit you get comp_units.  So we can use
        this to test that our callback gets called at the right depth."""

        target = self.make_target_and_import()
        extra_args = self.make_extra_args()

        file_list = lldb.SBFileSpecList()
        module_list = lldb.SBFileSpecList()
        module_list.Append(lldb.SBFileSpec("a.out"))

        # Make a breakpoint that has no __get_depth__, check that that is converted to eSearchDepthModule:
        bkpt = target.BreakpointCreateFromScript(
            "resolver.Resolver", extra_args, module_list, file_list
        )
        self.assertGreater(bkpt.GetNumLocations(), 0, "Resolver got no locations.")
        self.expect(
            "script print(resolver.Resolver.got_files)",
            substrs=["2"],
            msg="Was only passed modules",
        )
        print(f"Made first breakpoint: {bkpt}")
        bkpt = None
        # Make a breakpoint that asks for modules, check that we didn't get any files:
        bkpt = target.BreakpointCreateFromScript(
            "resolver.ResolverModuleDepth", extra_args, module_list, file_list
        )
        print(f"Made Second breakpoint: {bkpt}")
        self.assertGreater(
            bkpt.GetNumLocations(), 0, "ResolverModuleDepth got no locations."
        )
        self.expect(
            "script print(resolver.Resolver.got_files)",
            substrs=["2"],
            msg="Was only passed modules",
        )

        # Make a breakpoint that asks for compile units, check that we didn't get any files:
        bkpt = target.BreakpointCreateFromScript(
            "resolver.ResolverCUDepth", extra_args, module_list, file_list
        )
        self.assertGreater(
            bkpt.GetNumLocations(), 0, "ResolverCUDepth got no locations."
        )
        self.expect(
            "script print(resolver.Resolver.got_files)",
            substrs=["1"],
            msg="Was passed compile units",
        )

        # Make a breakpoint that returns a bad value - we should convert that to "modules" so check that:
        bkpt = target.BreakpointCreateFromScript(
            "resolver.ResolverBadDepth", extra_args, module_list, file_list
        )
        self.assertGreater(
            bkpt.GetNumLocations(), 0, "ResolverBadDepth got no locations."
        )
        self.expect(
            "script print(resolver.Resolver.got_files)",
            substrs=["2"],
            msg="Was only passed modules",
        )

        # Make a breakpoint that searches at function depth:
        bkpt = target.BreakpointCreateFromScript(
            "resolver.ResolverFuncDepth", extra_args, module_list, file_list
        )
        self.assertGreater(
            bkpt.GetNumLocations(), 0, "ResolverFuncDepth got no locations."
        )
        self.expect(
            "script print(resolver.Resolver.got_files)",
            substrs=["3"],
            msg="Was only passed modules",
        )
        self.expect(
            "script print(resolver.Resolver.func_list)",
            substrs=["test_func", "break_on_me", "main"],
            msg="Saw all the functions",
        )

    def do_test_cli(self):
        target = self.make_target_and_import()

        lldbutil.run_break_set_by_script(
            self, "resolver.Resolver", extra_options="-k symbol -v break_on_me"
        )

        # Make sure setting a resolver breakpoint doesn't pollute further breakpoint setting
        # by checking the description of a regular file & line breakpoint to make sure it
        # doesn't mention the Python Resolver function:
        bkpt_no = lldbutil.run_break_set_by_file_and_line(self, "main.c", 12)
        bkpt = target.FindBreakpointByID(bkpt_no)
        strm = lldb.SBStream()
        bkpt.GetDescription(strm, False)
        used_resolver = "I am a python breakpoint resolver" in strm.GetData()
        self.assertFalse(
            used_resolver,
            "Found the resolver description in the file & line breakpoint description.",
        )

        # Also make sure the breakpoint was where we expected:
        bp_loc = bkpt.GetLocationAtIndex(0)
        bp_sc = bp_loc.GetAddress().GetSymbolContext(lldb.eSymbolContextEverything)
        bp_se = bp_sc.GetLineEntry()
        self.assertEqual(bp_se.GetLine(), 12, "Got the right line number")
        self.assertEqual(
            bp_se.GetFileSpec().GetFilename(), "main.c", "Got the right filename"
        )

    def do_test_bad_options(self):
        target = self.make_target_and_import()

        self.expect(
            "break set -P resolver.Resolver -k a_key",
            error=True,
            msg="Missing value at end",
            substrs=['Key: "a_key" missing value'],
        )
        self.expect(
            "break set -P resolver.Resolver -v a_value",
            error=True,
            msg="Missing key at end",
            substrs=['Value: "a_value" missing matching key'],
        )
        self.expect(
            "break set -P resolver.Resolver -v a_value -k a_key -v another_value",
            error=True,
            msg="Missing key among args",
            substrs=['Value: "a_value" missing matching key'],
        )
        self.expect(
            "break set -P resolver.Resolver -k a_key -k a_key -v another_value",
            error=True,
            msg="Missing value among args",
            substrs=['Key: "a_key" missing value'],
        )

    def do_test_copy_from_dummy_target(self):
        # Import breakpoint scripted resolver.
        self.import_resolver_script()

        # Create a scripted breakpoint.
        self.runCmd(
            "breakpoint set -P resolver.Resolver -k symbol -v break_on_me",
            BREAKPOINT_CREATED,
        )

        # This is the function to remove breakpoints from the dummy target
        # to get a clean state for the next test case.
        def cleanup():
            self.runCmd("breakpoint delete -D -f", check=False)
            self.runCmd("breakpoint list", check=False)

        # Execute the cleanup function during test case tear down.
        self.addTearDownHook(cleanup)

        # Check that target creating doesn't crash.
        target = self.make_target()
