"""
Test SBThread APIs.
"""

import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
from lldbsuite.test.lldbutil import get_stopped_thread, get_caller_symbol


class ThreadAPITestCase(TestBase):
    SHARED_BUILD_TESTCASE = False

    def test_get_process(self):
        """Test Python SBThread.GetProcess() API."""
        self.build()
        self.get_process()

    def test_get_stop_description(self):
        """Test Python SBThread.GetStopDescription() API."""
        self.build()
        self.get_stop_description()

    def test_run_to_address(self):
        """Test Python SBThread.RunToAddress() API."""
        # We build a different executable than the default build() does.
        d = {"CXX_SOURCES": "main2.cpp", "EXE": self.exe_name}
        self.build(dictionary=d)
        self.setTearDownCleanup(dictionary=d)
        self.run_to_address(self.exe_name)

    @skipIfAsan  # The output looks different under ASAN.
    @expectedFailureAll(oslist=["linux"], archs=["arm$"], bugnumber="llvm.org/pr45892")
    @expectedFailureAll(oslist=["windows"])
    def test_step_out_of_malloc_into_function_b(self):
        """Test Python SBThread.StepOut() API to step out of a malloc call where the call site is at function b()."""
        # We build a different executable than the default build() does.
        d = {"CXX_SOURCES": "main2.cpp", "EXE": self.exe_name}
        self.build(dictionary=d)
        self.setTearDownCleanup(dictionary=d)
        self.step_out_of_malloc_into_function_b(self.exe_name)

    def test_step_over_3_times(self):
        """Test Python SBThread.StepOver() API."""
        # We build a different executable than the default build() does.
        d = {"CXX_SOURCES": "main2.cpp", "EXE": self.exe_name}
        self.build(dictionary=d)
        self.setTearDownCleanup(dictionary=d)
        self.step_over_3_times(self.exe_name)

    def test_negative_indexing(self):
        """Test SBThread.frame with negative indexes."""
        self.build()
        self.validate_negative_indexing()
 
    @skipIfWasm  # the test calls a function with an expression
    def test_StepInstruction(self):
        """Test that StepInstruction preserves the plan stack."""
        self.build()
        self.step_instruction_in_called_function()

    def setUp(self):
        # Call super's setUp().
        TestBase.setUp(self)
        # Find the line number within main.cpp to break inside main().
        self.break_line = line_number(
            "main.cpp", "// Set break point at this line and check variable 'my_char'."
        )
        # Find the line numbers within main2.cpp for
        # step_out_of_malloc_into_function_b() and step_over_3_times().
        self.step_out_of_malloc = line_number(
            "main2.cpp", "// thread step-out of malloc into function b."
        )
        self.after_3_step_overs = line_number(
            "main2.cpp", "// we should reach here after 3 step-over's."
        )

        # We'll use the test method name as the exe_name for executable
        # compiled from main2.cpp.
        self.exe_name = self.testMethodName

    def get_process(self):
        """Test Python SBThread.GetProcess() API."""
        _, process, thread, _ = lldbutil.run_to_line_breakpoint(
            self, lldb.SBFileSpec("main.cpp"), self.break_line
        )
        self.runCmd("breakpoint list")
        self.runCmd("process status")

        proc_of_thread = thread.GetProcess()
        self.trace("proc_of_thread:", proc_of_thread)
        self.assertEqual(proc_of_thread.GetProcessID(), process.GetProcessID())

    def get_stop_description(self):
        """Test Python SBThread.GetStopDescription() API."""
        _, _, thread, _ = lldbutil.run_to_line_breakpoint(
            self, lldb.SBFileSpec("main.cpp"), self.break_line
        )

        # Get the stop reason. GetStopDescription expects that we pass in the size of the description
        # we expect plus an additional byte for the null terminator.

        # Test with a buffer that is exactly as large as the expected stop reason.
        self.assertEqual(
            "breakpoint 1.1", thread.GetStopDescription(len("breakpoint 1.1") + 1)
        )

        # Test some smaller buffer sizes.
        self.assertEqual("breakpoint", thread.GetStopDescription(len("breakpoint") + 1))
        self.assertEqual("break", thread.GetStopDescription(len("break") + 1))
        self.assertEqual("b", thread.GetStopDescription(len("b") + 1))

        # Test that we can pass in a much larger size and still get the right output.
        self.assertEqual(
            "breakpoint 1.1", thread.GetStopDescription(len("breakpoint 1.1") + 100)
        )

        # Test the stream variation
        stream = lldb.SBStream()
        self.assertTrue(thread.GetStopDescription(stream))
        self.assertEqual("breakpoint 1.1", stream.GetData())

    def step_out_of_malloc_into_function_b(self, exe_name):
        """Test Python SBThread.StepOut() API to step out of a malloc call where the call site is at function b()."""
        # On ELF platforms malloc lives in the C library, which is only loaded
        # once the process is running, so the breakpoint has no location yet.
        target, process, _, breakpoint = lldbutil.run_to_name_breakpoint(
            self, "malloc", exe_name=exe_name, has_locations_before_run=False
        )

        while True:
            thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint)
            self.assertTrue(
                thread.IsValid(), "There should be a thread stopped due to breakpoint"
            )
            caller_symbol = get_caller_symbol(thread)
            if not caller_symbol:
                self.fail("Test failed: could not locate the caller symbol of malloc")

            # Our top frame may be an inlined function in malloc() (e.g., on
            # FreeBSD).  Apply a simple heuristic of stepping out until we find
            # a non-malloc caller
            while caller_symbol.startswith("malloc"):
                thread.StepOut()
                self.assertTrue(
                    thread.IsValid(), "Thread valid after stepping to outer malloc"
                )
                caller_symbol = get_caller_symbol(thread)

            if caller_symbol == "b(int)":
                break
            process.Continue()

        # On Linux malloc calls itself in some case. Remove the breakpoint because we don't want
        # to hit it during step-out.
        target.BreakpointDelete(breakpoint.GetID())

        thread.StepOut()
        self.runCmd("thread backtrace")
        self.assertEqual(
            thread.GetFrameAtIndex(0).GetLineEntry().GetLine(),
            self.step_out_of_malloc,
            "step out of malloc into function b is successful",
        )

    def step_over_3_times(self, exe_name):
        """Test Python SBThread.StepOver() API."""
        _, _, thread, _ = lldbutil.run_to_line_breakpoint(
            self,
            lldb.SBFileSpec("main2.cpp"),
            self.step_out_of_malloc,
            exe_name=exe_name,
        )
        self.runCmd("breakpoint list")

        # Frame #0 should be on self.step_out_of_malloc.
        self.runCmd("thread backtrace")
        frame0 = thread.GetFrameAtIndex(0)
        lineEntry = frame0.GetLineEntry()
        self.assertEqual(lineEntry.GetLine(), self.step_out_of_malloc)

        thread.StepOver()
        thread.StepOver()
        thread.StepOver()
        self.runCmd("thread backtrace")

        # Verify that we are stopped at the correct source line number in
        # main2.cpp.
        frame0 = thread.GetFrameAtIndex(0)
        lineEntry = frame0.GetLineEntry()
        self.assertStopReason(thread.GetStopReason(), lldb.eStopReasonPlanComplete)
        # Expected failure with clang as the compiler.
        # rdar://problem/9223880
        #
        # Which has been fixed on the lldb by compensating for inaccurate line
        # table information with r140416.
        self.assertEqual(lineEntry.GetLine(), self.after_3_step_overs)

    def run_to_address(self, exe_name):
        """Test Python SBThread.RunToAddress() API."""
        target, _, thread, _ = lldbutil.run_to_line_breakpoint(
            self,
            lldb.SBFileSpec("main2.cpp"),
            self.step_out_of_malloc,
            exe_name=exe_name,
        )
        self.runCmd("breakpoint list")

        # Frame #0 should be on self.step_out_of_malloc.
        self.runCmd("thread backtrace")
        frame0 = thread.GetFrameAtIndex(0)
        lineEntry = frame0.GetLineEntry()
        self.assertEqual(lineEntry.GetLine(), self.step_out_of_malloc)

        # Get the start/end addresses for this line entry.
        start_addr = lineEntry.GetStartAddress().GetLoadAddress(target)
        end_addr = lineEntry.GetEndAddress().GetLoadAddress(target)
        if self.TraceOn():
            print("start addr:", hex(start_addr))
            print("end addr:", hex(end_addr))

        # Disable the breakpoint.
        self.assertTrue(target.DisableAllBreakpoints())
        self.runCmd("breakpoint list")

        thread.StepOver()
        thread.StepOver()
        thread.StepOver()
        self.runCmd("thread backtrace")

        # Now ask SBThread to run to the address 'start_addr' we got earlier, which
        # corresponds to self.step_out_of_malloc line entry's start address.
        thread.RunToAddress(start_addr)
        self.runCmd("process status")
        # self.runCmd("thread backtrace")

    def validate_negative_indexing(self):
        _, _, thread, _ = lldbutil.run_to_line_breakpoint(
            self, lldb.SBFileSpec("main.cpp"), self.break_line
        )
        self.runCmd("breakpoint list")
        self.runCmd("process status")

        pos_range = range(thread.num_frames)
        neg_range = range(thread.num_frames, 0, -1)
        for pos, neg in zip(pos_range, neg_range):
            self.assertEqual(thread.frame[pos].idx, thread.frame[-neg].idx)

    def step_instruction_in_called_function(self):
        main_file_spec = lldb.SBFileSpec("main.cpp")
        target, process, thread, bkpt = lldbutil.run_to_source_breakpoint(
            self, "Set break point at this line", main_file_spec
        )
        options = lldb.SBExpressionOptions()
        options.SetIgnoreBreakpoints(False)

        call_me_bkpt = target.BreakpointCreateBySourceRegex(
            "Set a breakpoint in call_me", main_file_spec
        )
        self.assertGreater(
            call_me_bkpt.GetNumLocations(), 0, "Got at least one location in call_me"
        )

        # On Windows this may be the full name "void __cdecl call_me(bool)",
        # elsewhere it's just "call_me(bool)".
        expected_name = r".*call_me\(bool\)$"

        # Now run the expression, this will fail because we stopped at a breakpoint:
        self.runCmd("expr -i 0 -- call_me(true)", check=False)
        # Now we should be stopped in call_me:
        self.assertRegex(
            thread.frames[0].name, expected_name, "Stopped in call_me(bool)"
        )

        # Now do a various API steps.  These should not cause the expression context to get unshipped:
        thread.StepInstruction(False)
        self.assertRegex(
            thread.frames[0].name,
            expected_name,
            "Still in call_me(bool) after StepInstruction",
        )
        thread.StepInstruction(True)
        self.assertRegex(
            thread.frames[0].name,
            expected_name,
            "Still in call_me(bool) after NextInstruction",
        )
        thread.StepInto()
        self.assertRegex(
            thread.frames[0].name,
            expected_name,
            "Still in call_me(bool) after StepInto",
        )
        thread.StepOver(False)
        self.assertRegex(
            thread.frames[0].name,
            expected_name,
            "Still in call_me(bool) after StepOver",
        )
