"""
Test thread step-in, step-over and step-out work with the "Avoid no debug" option.
"""

from __future__ import print_function



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


class StepAvoidsNoDebugTestCase(TestBase):

    mydir = TestBase.compute_mydir(__file__)

    @add_test_categories(['pyapi'])
    def test_step_out_with_python(self):
        """Test stepping out using avoid-no-debug with dsyms."""
        self.build()
        self.get_to_starting_point()
        self.do_step_out_past_nodebug()

    @add_test_categories(['pyapi'])
    @decorators.expectedFailureAll(
        compiler="gcc", bugnumber="llvm.org/pr28549")
    @decorators.expectedFailureAll(
        compiler="clang",
        compiler_version=[
            ">=",
            "3.9"],
        archs=["i386"],
        bugnumber="llvm.org/pr28549")
    def test_step_over_with_python(self):
        """Test stepping over using avoid-no-debug with dwarf."""
        self.build()
        self.get_to_starting_point()
        self.do_step_over_past_nodebug()

    @add_test_categories(['pyapi'])
    @decorators.expectedFailureAll(
        compiler="gcc", bugnumber="llvm.org/pr28549")
    @decorators.expectedFailureAll(
        compiler="clang",
        compiler_version=[
            ">=",
            "3.9"],
        archs=["i386"],
        bugnumber="llvm.org/pr28549")
    @expectedFailureAll(oslist=["ios", "tvos", "bridgeos"], bugnumber="<rdar://problem/34026777>")  # lldb doesn't step past last source line in function on arm64
    def test_step_in_with_python(self):
        """Test stepping in using avoid-no-debug with dwarf."""
        self.build()
        self.get_to_starting_point()
        self.do_step_in_past_nodebug()

    def setUp(self):
        TestBase.setUp(self)
        self.main_source = "with-debug.c"
        self.main_source_spec = lldb.SBFileSpec("with-debug.c")
        self.dbg.HandleCommand(
            "settings set target.process.thread.step-out-avoid-nodebug true")

    def tearDown(self):
        self.dbg.HandleCommand(
            "settings set target.process.thread.step-out-avoid-nodebug false")
        TestBase.tearDown(self)

    def hit_correct_line(self, pattern):
        target_line = line_number(self.main_source, pattern)
        self.assertTrue(
            target_line != 0,
            "Could not find source pattern " +
            pattern)
        cur_line = self.thread.frames[0].GetLineEntry().GetLine()
        self.assertTrue(
            cur_line == target_line,
            "Stepped to line %d instead of expected %d with pattern '%s'." %
            (cur_line,
             target_line,
             pattern))

    def hit_correct_function(self, pattern):
        name = self.thread.frames[0].GetFunctionName()
        self.assertTrue(
            pattern in name, "Got to '%s' not the expected function '%s'." %
            (name, pattern))

    def get_to_starting_point(self):
        exe = self.getBuildArtifact("a.out")
        error = lldb.SBError()

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

        inner_bkpt = self.target.BreakpointCreateBySourceRegex(
            "Stop here and step out of me", self.main_source_spec)
        self.assertTrue(inner_bkpt, VALID_BREAKPOINT)

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

        self.assertTrue(self.process, PROCESS_IS_VALID)

        # Now finish, and make sure the return value is correct.
        threads = lldbutil.get_threads_stopped_at_breakpoint(
            self.process, inner_bkpt)
        self.assertTrue(len(threads) == 1, "Stopped at inner breakpoint.")
        self.thread = threads[0]

    def do_step_out_past_nodebug(self):
        # The first step out takes us to the called_from_nodebug frame, just to make sure setting
        # step-out-avoid-nodebug doesn't change the behavior in frames with
        # debug info.
        self.thread.StepOut()
        self.hit_correct_line(
            "intermediate_return_value = called_from_nodebug_actual(some_value)")
        self.thread.StepOut()
        self.hit_correct_line(
            "int return_value = no_debug_caller(5, called_from_nodebug)")

    def do_step_over_past_nodebug(self):
        self.thread.StepOver()
        self.hit_correct_line(
            "intermediate_return_value = called_from_nodebug_actual(some_value)")
        self.thread.StepOver()
        self.hit_correct_line("return intermediate_return_value")
        self.thread.StepOver()
        # Note, lldb doesn't follow gdb's distinction between "step-out" and "step-over/step-in"
        # when exiting a frame.  In all cases we leave the pc at the point where we exited the
        # frame.  In gdb, step-over/step-in move to the end of the line they stepped out to.
        # If we ever change this we will need to fix this test.
        self.hit_correct_line(
            "int return_value = no_debug_caller(5, called_from_nodebug)")

    def do_step_in_past_nodebug(self):
        self.thread.StepInto()
        self.hit_correct_line(
            "intermediate_return_value = called_from_nodebug_actual(some_value)")
        self.thread.StepInto()
        self.hit_correct_line("return intermediate_return_value")
        self.thread.StepInto()
        # Note, lldb doesn't follow gdb's distinction between "step-out" and "step-over/step-in"
        # when exiting a frame.  In all cases we leave the pc at the point where we exited the
        # frame.  In gdb, step-over/step-in move to the end of the line they stepped out to.
        # If we ever change this we will need to fix this test.
        self.hit_correct_line(
            "int return_value = no_debug_caller(5, called_from_nodebug)")
