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

from __future__ import print_function


import unittest2

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


class UnwindFromExpressionTest(TestBase):

    mydir = TestBase.compute_mydir(__file__)
    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.assertTrue(
            val.GetError().Success(),
            "We did complete the execution.")
        self.assertEquals(47, val.GetValueAsSigned())


    @add_test_categories(['pyapi'])
    @expectedFailureAll(oslist=["windows"])
    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.assertTrue(
            "Execution was interrupted, reason: breakpoint" in 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.
        error = thread.UnwindInnermostExpression()
        self.assertTrue(error.Success(), "We succeeded in unwinding")

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