""" Test that stop-on-sharedlibrary-events works and cooperates with breakpoints. """
import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil

class TestStopOnSharedlibraryEvents(TestBase):

    mydir = TestBase.compute_mydir(__file__)

    @skipIfRemote
    @skipIfWindows
    @no_debug_info_test
    def test_stopping_breakpoints(self):
        self.do_test()

    @skipIfRemote
    @skipIfWindows
    @no_debug_info_test
    def test_auto_continue(self):
        def auto_continue(bkpt):
            bkpt.SetAutoContinue(True)
        self.do_test(auto_continue)

    @skipIfRemote
    @skipIfWindows
    @no_debug_info_test
    def test_failing_condition(self):
        def condition(bkpt):
            bkpt.SetCondition("1 == 2")
        self.do_test(condition)
        
    @skipIfRemote
    @skipIfWindows
    @no_debug_info_test
    def test_continue_callback(self):
        def bkpt_callback(bkpt):
            bkpt.SetScriptCallbackBody("return False")
        self.do_test(bkpt_callback)

    def do_test(self, bkpt_modifier = None):
        self.build()
        main_spec = lldb.SBFileSpec("main.cpp")
        # Launch and stop before the dlopen call.
        target, process, thread, _ = lldbutil.run_to_source_breakpoint(self,
                "// Set a breakpoint here", main_spec, extra_images=["load_a",
                    "load_b"])

        # Now turn on shared library events, continue and make sure we stop for the event.
        self.runCmd("settings set target.process.stop-on-sharedlibrary-events 1")
        self.addTearDownHook(lambda: self.runCmd(
            "settings set target.process.stop-on-sharedlibrary-events 0"))

        # Since I don't know how to check that we are at the "right place" to stop for
        # shared library events, make an breakpoint after the load is done and
        # make sure we don't stop there:
        backstop_bkpt_1 = target.BreakpointCreateBySourceRegex("Set another here - we should not hit this one", main_spec)
        self.assertGreater(backstop_bkpt_1.GetNumLocations(), 0, "Set our second breakpoint")
        
        process.Continue() 
        self.assertEqual(process.GetState(), lldb.eStateStopped, "We didn't stop for the load")
        self.assertEqual(backstop_bkpt_1.GetHitCount(), 0, "Hit our backstop breakpoint")
        
        # We should be stopped after the library is loaded, check that:
        found_it = False
        for module in target.modules:
            if module.file.basename.find("load_a") > -1:
                found_it = True
                break
        self.assertTrue(found_it, "Found the loaded module.")

        # Now capture the place where we stopped so we can set a breakpoint and make
        # sure the breakpoint there works correctly:
        load_address = process.GetSelectedThread().frames[0].addr
        load_bkpt = target.BreakpointCreateBySBAddress(load_address)
        self.assertGreater(load_bkpt.GetNumLocations(), 0, "Set the load breakpoint")

        backstop_bkpt_1.SetEnabled(False)

        backstop_bkpt_2 = target.BreakpointCreateBySourceRegex("Set a third here - we should not hit this one", main_spec)
        self.assertGreater(backstop_bkpt_2.GetNumLocations(), 0, "Set our third breakpoint")
            
        if bkpt_modifier == None:
            process.Continue()
            self.assertEqual(process.GetState(), lldb.eStateStopped, "We didn't stop for the load")
            self.assertEqual(backstop_bkpt_2.GetHitCount(), 0, "Hit our backstop breakpoint")
            self.assertEqual(thread.stop_reason, lldb.eStopReasonBreakpoint, "We attributed the stop to the breakpoint")
            self.assertEqual(load_bkpt.GetHitCount(), 1, "We hit our breakpoint at the load address")
        else:
            bkpt_modifier(load_bkpt)
            process.Continue()
            self.assertEqual(process.GetState(), lldb.eStateStopped, "We didn't stop")
            self.assertTrue(thread.IsValid(), "Our thread was no longer valid.")
            self.assertEqual(thread.stop_reason, lldb.eStopReasonBreakpoint, "We didn't hit some breakpoint")
            self.assertEqual(backstop_bkpt_2.GetHitCount(), 1, "We continued to the right breakpoint")

        
        
        
        
