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

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

        
        
        
        
