"""Test stepping over and into inlined functions."""

import os, time
import unittest2
import lldb
import lldbutil
from lldbtest import *

class TestInlineStepping(TestBase):

    mydir = os.path.join("functionalities", "inline-stepping")

    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
    @python_api_test
    @dsym_test
    def test_with_dsym_and_python_api(self):
        """Test stepping over and into inlined functions."""
        self.buildDsym()
        self.inline_stepping()

    @expectedFailureGcc # Some versions of GCC emit DWARF that considers functions to start at the line with the '{' whereas this test
                        # expects the first line of a function to be the first line of source (i.e. what clang does). As such, this test
                        # fails with some versions of GCC.
    @python_api_test
    @dwarf_test
    def test_with_dwarf_and_python_api(self):
        """Test stepping over and into inlined functions."""
        self.buildDwarf()
        self.inline_stepping()

    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
    @python_api_test
    @dsym_test
    def test_step_over_with_dsym_and_python_api(self):
        """Test stepping over and into inlined functions."""
        self.buildDsym()
        self.inline_stepping_step_over()

    @expectedFailureGcc # Some versions of GCC emit DWARF that considers functions to start at the line with the '{' whereas this test
                        # expects the first line of a function to be the first line of source (i.e. what clang does). As such, this test
                        # fails with some versions of GCC.
    @python_api_test
    @dwarf_test
    def test_step_over_with_dwarf_and_python_api(self):
        """Test stepping over and into inlined functions."""
        self.buildDwarf()
        self.inline_stepping_step_over()

    def setUp(self):
        # Call super's setUp().
        TestBase.setUp(self)
        # Find the line numbers that we will step to in main:
        self.main_source = "calling.cpp"
        self.source_lines = {}
        functions = ['caller_ref_1', 'caller_ref_2', 'inline_ref_1', 'inline_ref_2', 'called_by_inline_ref', 'caller_trivial_1', 'caller_trivial_2', 'inline_trivial_1', 'inline_trivial_2', 'called_by_inline_trivial' ]
        for name in functions:
            self.source_lines[name] = line_number(self.main_source, "// In " + name + ".")
        self.main_source_spec = lldb.SBFileSpec (self.main_source)

    def do_step(self, step_type, destination_line_entry):
        expected_stack_depth = self.thread.GetNumFrames()
        if step_type == "into":
            expected_stack_depth += 1
            self.thread.StepInto()
        elif step_type == "out":
            expected_stack_depth -= 1
            self.thread.StepOut()
        elif step_type == "over":
            self.thread.StepOver()
        else:
            self.fail ("Unrecognized step type: " + step_type)

        threads = lldbutil.get_stopped_threads (self.process, lldb.eStopReasonPlanComplete)
        if len(threads) != 1:
            destination_description = lldb.SBStream()
            destination_line_entry.GetDescription(destination_description)
            self.fail ("Failed to stop due to step " + step_type + " operation stepping to: " + destination_description.GetData())

        self.thread = threads[0]

        stop_line_entry = self.thread.GetFrameAtIndex(0).GetLineEntry()
        self.assertTrue (stop_line_entry.IsValid(), "Stop line entry was not valid.")

        # Don't use the line entry equal operator because we don't care about the column number.
        stop_at_right_place = (stop_line_entry.GetFileSpec() == destination_line_entry.GetFileSpec() and stop_line_entry.GetLine() == destination_line_entry.GetLine())
        if stop_at_right_place == False:
            destination_description = lldb.SBStream()
            destination_line_entry.GetDescription(destination_description)

            actual_description = lldb.SBStream()
            stop_line_entry.GetDescription(actual_description)

            self.fail ("Step " + step_type + " stopped at wrong place: expected: " + destination_description.GetData() + " got: " + actual_description.GetData() + ".")

        real_stack_depth = self.thread.GetNumFrames()

        if real_stack_depth != expected_stack_depth:
            destination_description = lldb.SBStream()
            destination_line_entry.GetDescription(destination_description)
            self.fail ("Step %s to %s got wrong number of frames, should be: %d was: %d."%(step_type, destination_description.GetData(), expected_stack_depth, real_stack_depth))
            
    def run_step_sequence(self, step_sequence):
        """This function takes a list of duples instructing how to run the program.  The first element in each duple is
           a source pattern for the target location, and the second is the operation that will take you from the current
           source location to the target location.  It will then run all the steps in the sequence.
           It will check that you arrived at the expected source location at each step, and that the stack depth changed 
           correctly for the operation in the sequence."""

        target_line_entry = lldb.SBLineEntry()
        target_line_entry.SetFileSpec(self.main_source_spec)

        for step_pattern in step_sequence:
            step_stop_line = line_number (self.main_source, step_pattern[0])
            target_line_entry.SetLine(step_stop_line)
            self.do_step (step_pattern[1], target_line_entry)
        

    def inline_stepping(self):
        """Use Python APIs to test stepping over and hitting breakpoints."""
        exe = os.path.join(os.getcwd(), "a.out")

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

        break_1_in_main = target.BreakpointCreateBySourceRegex ('// Stop here and step over to set up stepping over.', self.main_source_spec)
        self.assertTrue(break_1_in_main, VALID_BREAKPOINT)

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

        self.assertTrue(self.process, PROCESS_IS_VALID)

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

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

        self.thread = threads[0]

        # Step over the inline_value = 0 line to get us to inline_trivial_1 called from main.  Doing it this way works
        # around a bug in lldb where the breakpoint on the containing line of an inlined function with no return value
        # gets set past the insertion line in the function.
        # Then test stepping over a simple inlined function.  Note, to test all the parts of the inlined stepping
        # the calls inline_stepping_1 and inline_stepping_2 should line up at the same address, that way we will test
        # the "virtual" stepping.  
        # FIXME: Put in a check to see if that is true and warn if it is not.

        step_sequence = [["// At inline_trivial_1 called from main.", "over"], 
                         ["// At first call of caller_trivial_1 in main.", "over"]]
        self.run_step_sequence(step_sequence)
           
        # Now step from caller_ref_1 all the way into called_by_inline_trivial

        step_sequence = [["// In caller_trivial_1.", "into"], 
                         ["// In caller_trivial_2.", "into"], 
                         ["// In inline_trivial_1.", "into"],
                         ["// In inline_trivial_2.", "into"],
                         ["// At caller_by_inline_trivial in inline_trivial_2.", "over"],
                         ["// In called_by_inline_trivial.", "into"]]
        self.run_step_sequence(step_sequence)

        # Now run to the inline_trivial_1 just before the immediate step into inline_trivial_2:

        break_2_in_main = target.BreakpointCreateBySourceRegex ('// At second call of caller_trivial_1 in main.', self.main_source_spec)
        self.assertTrue(break_2_in_main, VALID_BREAKPOINT)

        threads = lldbutil.continue_to_breakpoint (self.process, break_2_in_main)
        self.assertTrue (len(threads) == 1, "Successfully ran to call site of second caller_trivial_1 call.")
        self.thread = threads[0]
        
        step_sequence = [["// In caller_trivial_1.", "into"], 
                         ["// In caller_trivial_2.", "into"], 
                         ["// In inline_trivial_1.", "into"]]
        self.run_step_sequence(step_sequence)

        # Then call some trivial function, and make sure we end up back where we were in the inlined call stack:
        
        frame = self.thread.GetFrameAtIndex(0)
        before_line_entry = frame.GetLineEntry()
        value = frame.EvaluateExpression ("function_to_call()")
        after_line_entry = frame.GetLineEntry()

        self.assertTrue (before_line_entry.GetLine() == after_line_entry.GetLine(), "Line entry before and after function calls are the same.")

        # Now make sure stepping OVER in the middle of the stack works, and then check finish from the inlined frame:

        step_sequence = [["// At increment in inline_trivial_1.", "over"],
                         ["// At increment in caller_trivial_2.", "out"]]
        self.run_step_sequence(step_sequence)


        # Now run to the place in main just before the first call to caller_ref_1:

        break_3_in_main = target.BreakpointCreateBySourceRegex ('// At first call of caller_ref_1 in main.', self.main_source_spec)
        self.assertTrue(break_3_in_main, VALID_BREAKPOINT)

        threads = lldbutil.continue_to_breakpoint (self.process, break_3_in_main)
        self.assertTrue (len(threads) == 1, "Successfully ran to call site of first caller_ref_1 call.")
        self.thread = threads[0]

        step_sequence = [["// In caller_ref_1.", "into"],
                         ["// In caller_ref_2.", "into"],
                         ["// In inline_ref_1.", "into"],
                         ["// In inline_ref_2.", "into"],
                         ["// In called_by_inline_ref.", "into"],
                         ["// In inline_ref_2.", "out"],
                         ["// In inline_ref_1.", "out"],
                         ["// At increment in inline_ref_1.", "over"],
                         ["// In caller_ref_2.", "out"],
                         ["// At increment in caller_ref_2.", "over"]]
        self.run_step_sequence (step_sequence)

    def inline_stepping_step_over(self):
        """Use Python APIs to test stepping over and hitting breakpoints."""
        exe = os.path.join(os.getcwd(), "a.out")

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

        break_1_in_main = target.BreakpointCreateBySourceRegex ('// At second call of caller_ref_1 in main.', self.main_source_spec)
        self.assertTrue(break_1_in_main, VALID_BREAKPOINT)

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

        self.assertTrue(self.process, PROCESS_IS_VALID)

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

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

        self.thread = threads[0]

        step_sequence = [["// In caller_ref_1.", "into"],
                         ["// In caller_ref_2.", "into"],
                         ["// At increment in caller_ref_2.", "over"]]
        self.run_step_sequence (step_sequence)

        
        

if __name__ == '__main__':
    import atexit
    lldb.SBDebugger.Initialize()
    atexit.register(lambda: lldb.SBDebugger.Terminate())
    unittest2.main()
