"""Test stepping over vrs. hitting breakpoints & subsequent stepping in various forms."""

from __future__ import print_function


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


class TestCStepping(TestBase):

    mydir = TestBase.compute_mydir(__file__)

    def setUp(self):
        # Call super's setUp().
        TestBase.setUp(self)
        # Find the line numbers that we will step to in main:
        self.main_source = "main.c"

    @add_test_categories(['pyapi', 'basic_process'])
    @expectedFailureAll(oslist=['freebsd'], bugnumber='llvm.org/pr17932')
    @expectedFailureAll(oslist=["linux"], bugnumber="llvm.org/pr14437")
    @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24777")
    def test_and_python_api(self):
        """Test stepping over vrs. hitting breakpoints & subsequent stepping in various forms."""
        self.build()
        exe = self.getBuildArtifact("a.out")

        target = self.dbg.CreateTarget(exe)
        self.assertTrue(target, VALID_TARGET)

        self.main_source_spec = lldb.SBFileSpec(self.main_source)

        breakpoints_to_disable = []

        break_1_in_main = target.BreakpointCreateBySourceRegex(
            '// frame select 2, thread step-out while stopped at .c.1..',
            self.main_source_spec)
        self.assertTrue(break_1_in_main, VALID_BREAKPOINT)
        breakpoints_to_disable.append(break_1_in_main)

        break_in_a = target.BreakpointCreateBySourceRegex(
            '// break here to stop in a before calling b', self.main_source_spec)
        self.assertTrue(break_in_a, VALID_BREAKPOINT)
        breakpoints_to_disable.append(break_in_a)

        break_in_b = target.BreakpointCreateBySourceRegex(
            '// thread step-out while stopped at .c.2..', self.main_source_spec)
        self.assertTrue(break_in_b, VALID_BREAKPOINT)
        breakpoints_to_disable.append(break_in_b)

        break_in_c = target.BreakpointCreateBySourceRegex(
            '// Find the line number of function .c. here.', self.main_source_spec)
        self.assertTrue(break_in_c, VALID_BREAKPOINT)
        breakpoints_to_disable.append(break_in_c)

        # Now launch the process, and do not stop at entry point.
        process = target.LaunchSimple(
            None, None, self.get_process_working_directory())

        self.assertTrue(process, PROCESS_IS_VALID)

        # The stop reason of the thread should be breakpoint.
        threads = lldbutil.get_threads_stopped_at_breakpoint(
            process, break_1_in_main)

        if len(threads) != 1:
            self.fail("Failed to stop at first breakpoint in main.")

        thread = threads[0]

        # Get the stop id and for fun make sure it increases:
        old_stop_id = process.GetStopID()

        # Now step over, which should cause us to hit the breakpoint in "a"
        thread.StepOver()

        # The stop reason of the thread should be breakpoint.
        threads = lldbutil.get_threads_stopped_at_breakpoint(
            process, break_in_a)
        if len(threads) != 1:
            self.fail("Failed to stop at breakpoint in a.")

        # Check that the stop ID increases:
        new_stop_id = process.GetStopID()
        self.assertTrue(
            new_stop_id > old_stop_id,
            "Stop ID increases monotonically.")

        thread = threads[0]

        # Step over, and we should hit the breakpoint in b:
        thread.StepOver()

        threads = lldbutil.get_threads_stopped_at_breakpoint(
            process, break_in_b)
        if len(threads) != 1:
            self.fail("Failed to stop at breakpoint in b.")
        thread = threads[0]

        # Now try running some function, and make sure that we still end up in the same place
        # and with the same stop reason.
        frame = thread.GetFrameAtIndex(0)
        current_line = frame.GetLineEntry().GetLine()
        current_file = frame.GetLineEntry().GetFileSpec()
        current_bp = []
        current_bp.append(thread.GetStopReasonDataAtIndex(0))
        current_bp.append(thread.GetStopReasonDataAtIndex(1))

        stop_id_before_expression = process.GetStopID()
        stop_id_before_including_expressions = process.GetStopID(True)

        frame.EvaluateExpression("(int) printf (print_string)")

        frame = thread.GetFrameAtIndex(0)
        self.assertTrue(
            current_line == frame.GetLineEntry().GetLine(),
            "The line stayed the same after expression.")
        self.assertTrue(
            current_file == frame.GetLineEntry().GetFileSpec(),
            "The file stayed the same after expression.")
        self.assertTrue(
            thread.GetStopReason() == lldb.eStopReasonBreakpoint,
            "We still say we stopped for a breakpoint.")
        self.assertTrue(thread.GetStopReasonDataAtIndex(0) == current_bp[
                        0] and thread.GetStopReasonDataAtIndex(1) == current_bp[1], "And it is the same breakpoint.")

        # Also make sure running the expression didn't change the public stop id
        # but did change if we are asking for expression stops as well.
        stop_id_after_expression = process.GetStopID()
        stop_id_after_including_expressions = process.GetStopID(True)

        self.assertTrue(
            stop_id_before_expression == stop_id_after_expression,
            "Expression calling doesn't change stop ID")

        self.assertTrue(
            stop_id_after_including_expressions > stop_id_before_including_expressions,
            "Stop ID including expressions increments over expression call.")

        # Do the same thing with an expression that's going to crash, and make
        # sure we are still unchanged.

        frame.EvaluateExpression("((char *) 0)[0] = 'a'")

        frame = thread.GetFrameAtIndex(0)
        self.assertTrue(
            current_line == frame.GetLineEntry().GetLine(),
            "The line stayed the same after expression.")
        self.assertTrue(
            current_file == frame.GetLineEntry().GetFileSpec(),
            "The file stayed the same after expression.")
        self.assertTrue(
            thread.GetStopReason() == lldb.eStopReasonBreakpoint,
            "We still say we stopped for a breakpoint.")
        self.assertTrue(thread.GetStopReasonDataAtIndex(0) == current_bp[
                        0] and thread.GetStopReasonDataAtIndex(1) == current_bp[1], "And it is the same breakpoint.")

        # Now continue and make sure we just complete the step:
        # Disable all our breakpoints first - sometimes the compiler puts two line table entries in for the
        # breakpoint a "b" and we don't want to hit that.
        for bkpt in breakpoints_to_disable:
            bkpt.SetEnabled(False)

        process.Continue()

        self.assertTrue(thread.GetFrameAtIndex(0).GetFunctionName() == "a")
        self.assertTrue(thread.GetStopReason() == lldb.eStopReasonPlanComplete)

        # And one more time should get us back to main:
        process.Continue()

        self.assertTrue(thread.GetFrameAtIndex(0).GetFunctionName() == "main")
        self.assertTrue(thread.GetStopReason() == lldb.eStopReasonPlanComplete)

        # Now make sure we can call a function, break in the called function,
        # then have "continue" get us back out again:
        frame = thread.GetFrameAtIndex(0)
        frame = thread.GetFrameAtIndex(0)
        current_line = frame.GetLineEntry().GetLine()
        current_file = frame.GetLineEntry().GetFileSpec()

        break_in_b.SetEnabled(True)
        options = lldb.SBExpressionOptions()
        options.SetIgnoreBreakpoints(False)
        options.SetFetchDynamicValue(False)
        options.SetUnwindOnError(False)
        frame.EvaluateExpression("b (4)", options)

        threads = lldbutil.get_threads_stopped_at_breakpoint(
            process, break_in_b)

        if len(threads) != 1:
            self.fail("Failed to stop at breakpoint in b when calling b.")
        thread = threads[0]

        # So do a step over here to make sure we can still do that:

        thread.StepOver()

        # See that we are still in b:
        func_name = thread.GetFrameAtIndex(0).GetFunctionName()
        self.assertTrue(
            func_name == "b",
            "Should be in 'b', were in %s" %
            (func_name))

        # Okay, now if we continue, we will finish off our function call and we
        # should end up back in "a" as if nothing had happened:
        process.Continue()

        self.assertTrue(thread.GetFrameAtIndex(
            0).GetLineEntry().GetLine() == current_line)
        self.assertTrue(thread.GetFrameAtIndex(
            0).GetLineEntry().GetFileSpec() == current_file)

        # Now we are going to test step in targeting a function:

        break_in_b.SetEnabled(False)

        break_before_complex_1 = target.BreakpointCreateBySourceRegex(
            '// Stop here to try step in targeting b.', self.main_source_spec)
        self.assertTrue(break_before_complex_1, VALID_BREAKPOINT)

        break_before_complex_2 = target.BreakpointCreateBySourceRegex(
            '// Stop here to try step in targeting complex.', self.main_source_spec)
        self.assertTrue(break_before_complex_2, VALID_BREAKPOINT)

        break_before_complex_3 = target.BreakpointCreateBySourceRegex(
            '// Stop here to step targeting b and hitting breakpoint.', self.main_source_spec)
        self.assertTrue(break_before_complex_3, VALID_BREAKPOINT)

        break_before_complex_4 = target.BreakpointCreateBySourceRegex(
            '// Stop here to make sure bogus target steps over.', self.main_source_spec)
        self.assertTrue(break_before_complex_4, VALID_BREAKPOINT)

        threads = lldbutil.continue_to_breakpoint(
            process, break_before_complex_1)
        self.assertTrue(len(threads) == 1)
        thread = threads[0]
        break_before_complex_1.SetEnabled(False)

        thread.StepInto("b")
        self.assertTrue(thread.GetFrameAtIndex(0).GetFunctionName() == "b")

        # Now continue out and stop at the next call to complex.  This time
        # step all the way into complex:
        threads = lldbutil.continue_to_breakpoint(
            process, break_before_complex_2)
        self.assertTrue(len(threads) == 1)
        thread = threads[0]
        break_before_complex_2.SetEnabled(False)

        thread.StepInto("complex")
        self.assertTrue(thread.GetFrameAtIndex(
            0).GetFunctionName() == "complex")

        # Now continue out and stop at the next call to complex.  This time
        # enable breakpoints in a and c and then step targeting b:
        threads = lldbutil.continue_to_breakpoint(
            process, break_before_complex_3)
        self.assertTrue(len(threads) == 1)
        thread = threads[0]
        break_before_complex_3.SetEnabled(False)

        break_at_start_of_a = target.BreakpointCreateByName('a')
        break_at_start_of_c = target.BreakpointCreateByName('c')

        thread.StepInto("b")
        threads = lldbutil.get_stopped_threads(
            process, lldb.eStopReasonBreakpoint)

        self.assertTrue(len(threads) == 1)
        thread = threads[0]
        stop_break_id = thread.GetStopReasonDataAtIndex(0)
        self.assertTrue(stop_break_id == break_at_start_of_a.GetID()
                        or stop_break_id == break_at_start_of_c.GetID())

        break_at_start_of_a.SetEnabled(False)
        break_at_start_of_c.SetEnabled(False)

        process.Continue()
        self.assertTrue(thread.GetFrameAtIndex(0).GetFunctionName() == "b")

        # Now continue out and stop at the next call to complex.  This time
        # enable breakpoints in a and c and then step targeting b:
        threads = lldbutil.continue_to_breakpoint(
            process, break_before_complex_4)
        self.assertTrue(len(threads) == 1)
        thread = threads[0]
        break_before_complex_4.SetEnabled(False)

        thread.StepInto("NoSuchFunction")
        self.assertTrue(thread.GetFrameAtIndex(0).GetFunctionName() == "main")
