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

from __future__ import print_function



import os
import re
import lldb
import lldbsuite.test.lldbutil as lldbutil
import sys
from lldbsuite.test.lldbtest import *

class ReturnValueTestCase(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'])
    @expectedFailureGcc("llvm.org/pr19247")
    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'])
    @expectedFailureGcc("llvm.org/pr19247")
    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 = os.path.join(os.getcwd(), "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)")
