"""
Test stopping at a breakpoint in an expression, and unwinding from there.
"""

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


class UnwindFromExpressionTest(TestBase):
    main_spec = lldb.SBFileSpec("main.cpp", False)

    def build_and_run_to_bkpt(self):
        self.build()

        (target, process, self.thread, bkpt) = lldbutil.run_to_source_breakpoint(
            self, "// Set a breakpoint here to get started", self.main_spec
        )

        # Next set a breakpoint in this function, set up Expression options to stop on
        # breakpoint hits, and call the function.
        self.fun_bkpt = self.target().BreakpointCreateBySourceRegex(
            "// Stop inside the function here.", self.main_spec
        )
        self.assertTrue(self.fun_bkpt, VALID_BREAKPOINT)

    @no_debug_info_test
    @expectedFailureAll(bugnumber="llvm.org/pr33164")
    def test_conditional_bktp(self):
        """
        Test conditional breakpoint handling in the IgnoreBreakpoints = False case
        """
        self.build_and_run_to_bkpt()

        self.fun_bkpt.SetCondition("0")  # Should not get hit
        options = lldb.SBExpressionOptions()
        options.SetIgnoreBreakpoints(False)
        options.SetUnwindOnError(False)

        main_frame = self.thread.GetFrameAtIndex(0)
        val = main_frame.EvaluateExpression("second_function(47)", options)
        self.assertSuccess(val.GetError(), "We did complete the execution.")
        self.assertEqual(47, val.GetValueAsSigned())

    @add_test_categories(["pyapi"])
    @expectedFlakeyNetBSD
    def test_unwind_expression(self):
        """Test unwinding from an expression."""
        self.build_and_run_to_bkpt()

        # Run test with varying one thread timeouts to also test the halting
        # logic in the IgnoreBreakpoints = False case
        self.do_unwind_test(self.thread, self.fun_bkpt, 1000)
        self.do_unwind_test(self.thread, self.fun_bkpt, 100000)

    def do_unwind_test(self, thread, bkpt, timeout):
        #
        # Use Python API to evaluate expressions while stopped in a stack frame.
        #
        main_frame = thread.GetFrameAtIndex(0)

        options = lldb.SBExpressionOptions()
        options.SetIgnoreBreakpoints(False)
        options.SetUnwindOnError(False)
        options.SetOneThreadTimeoutInMicroSeconds(timeout)

        val = main_frame.EvaluateExpression("a_function_to_call()", options)

        self.assertTrue(val.GetError().Fail(), "We did not complete the execution.")
        error_str = val.GetError().GetCString()
        self.assertIn(
            "Expression execution hit a breakpoint: breakpoint",
            error_str,
            "And the reason was right.",
        )

        thread = lldbutil.get_one_thread_stopped_at_breakpoint(self.process(), bkpt)
        self.assertTrue(thread.IsValid(), "We are indeed stopped at our breakpoint")

        # Now unwind the expression, and make sure we got back to where we
        # started.
        self.assertSuccess(
            thread.UnwindInnermostExpression(), "We succeeded in unwinding"
        )

        cur_frame = thread.GetFrameAtIndex(0)
        self.assertTrue(cur_frame.IsEqual(main_frame), "We got back to the main frame.")
