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


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


class StepAvoidsNoDebugTestCase(TestBase):
    @add_test_categories(["pyapi"])
    @expectedFailureAll(
        archs=["aarch64"], oslist=["windows"], bugnumber="llvm.org/pr56292",
        debug_info=["dwarf", "dwo"]
    )
    def test_step_out_with_python(self):
        """Test stepping out using avoid-no-debug."""
        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"],
        oslist=no_match(["freebsd"]),
        bugnumber="llvm.org/pr28549",
    )
    @expectedFailureAll(
        archs=["aarch64"], oslist=["windows"], bugnumber="llvm.org/pr56292",
        debug_info=["dwarf", "dwo"]
    )
    @expectedFailureAll(archs=["arm64e"])
    def test_step_over_with_python(self):
        """Test stepping over using avoid-no-debug."""
        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"],
        oslist=no_match(["freebsd"]),
        bugnumber="llvm.org/pr28549",
    )
    @expectedFailureAll(
        archs=["aarch64"], oslist=["windows"], bugnumber="llvm.org/pr56292",
        debug_info=["dwarf", "dwo"]
    )
    @expectedFailureAll(archs=["arm64e"])
    def test_step_in_with_python(self):
        """Test stepping in using avoid-no-debug."""
        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.assertNotEqual(target_line, 0, "Could not find source pattern " + pattern)
        cur_line = self.thread.frames[0].GetLineEntry().GetLine()
        self.assertEqual(
            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.assertIn(
            pattern,
            name,
            "Got to '%s' not the expected function '%s'." % (name, pattern),
        )

    def get_to_starting_point(self):
        self.target, self.process, self.thread, _ = lldbutil.run_to_source_breakpoint(
            self, "Stop here and step out of me", self.main_source_spec
        )

    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)"
        )
