"""
Test that the run locker really does work to keep
us from running SB API that should only be run
while stopped.  This test is mostly concerned with
what happens between launch and first stop.
"""

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


class TestRunLocker(TestBase):

    NO_DEBUG_INFO_TESTCASE = True

    @expectedFailureAll(oslist=["windows"])
    def test_run_locker(self):
        """Test that the run locker is set correctly when we launch"""
        self.build()
        self.runlocker_test(False)

    @expectedFailureAll(oslist=["windows"])
    def test_run_locker_stop_at_entry(self):
        """Test that the run locker is set correctly when we launch"""
        self.build()
        self.runlocker_test(False)

    def setUp(self):
        # Call super's setUp().
        TestBase.setUp(self)
        self.main_source_file = lldb.SBFileSpec("main.c")

    def runlocker_test(self, stop_at_entry):
        """The code to stop at entry handles events slightly differently, so 
           we test both versions of process launch."""

        target = lldbutil.run_to_breakpoint_make_target(self)
        
        launch_info = target.GetLaunchInfo()
        if stop_at_entry:
            flags = launch_info.GetFlags()
            launch_info.SetFlags(flags | lldb.eLaunchFlagStopAtEntry)

        error = lldb.SBError()
        # We are trying to do things when the process is running, so
        # we have to run the debugger asynchronously.
        self.dbg.SetAsync(True)
        
        listener = lldb.SBListener("test-run-lock-listener")
        launch_info.SetListener(listener)
        process = target.Launch(launch_info, error)
        self.assertSuccess(error, "Launched the process")
        
        event = lldb.SBEvent()
        
        event_result = listener.WaitForEvent(10, event)
        self.assertTrue(event_result, "timed out waiting for launch")
        state_type = lldb.SBProcess.GetStateFromEvent(event)
        # We don't always see a launching...
        if state_type == lldb.eStateLaunching:
            event_result = listener.WaitForEvent(10, event)
            self.assertTrue(event_result, "Timed out waiting for running after launching")
            state_type = lldb.SBProcess.GetStateFromEvent(event)
            
        self.assertState(state_type, lldb.eStateRunning, "Didn't get a running event")
        
        # We aren't checking the entry state, but just making sure
        # the running state is set properly if we continue in this state.
        
        if stop_at_entry:
            event_result = listener.WaitForEvent(10, event)
            self.assertTrue(event_result, "Timed out waiting for stop at entry stop")
            state_type = lldb.SBProcess.GetStateFromEvent(event)
            self.assertState(state_type, eStateStopped, "Stop at entry stopped")
            process.Continue()

        # Okay, now the process is running, make sure we can't do things
        # you aren't supposed to do while running, and that we get some
        # actual error:
        val = target.EvaluateExpression("SomethingToCall()")
        error = val.GetError()
        self.assertTrue(error.Fail(), "Failed to run expression")
        print(f"Got Error: {error.GetCString()}")
        self.assertIn("can't evaluate expressions when the process is running", error.GetCString(), "Stopped by stop locker")

        # This should also fail if we try to use the script interpreter directly:
        interp = self.dbg.GetCommandInterpreter()
        result = lldb.SBCommandReturnObject()
        ret = interp.HandleCommand("script var = lldb.frame.EvaluateExpression('SomethingToCall()'); var.GetError().GetCString()", result)
        self.assertIn("can't evaluate expressions when the process is running", result.GetOutput())
