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

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