"""
Use lldb Python SBFrame API to get the argument values of the call stacks.
And other SBFrame API tests.
"""

import io

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


class FrameAPITestCase(TestBase):
    @skipIfWasm  # Wasm exposes no register sets, so there is no pc or sp register to read
    def test_get_arg_vals_for_call_stack(self):
        """Exercise SBFrame.GetVariables() API to get argument vals."""
        self.build()
        _, process, _, _ = lldbutil.run_to_name_breakpoint(
            self, "c", bkpt_module="a.out"
        )

        # Keeps track of the number of times 'a' is called where it is within a
        # depth of 3 of the 'c' leaf function.
        callsOfA = 0

        session = io.StringIO()
        while process.GetState() == lldb.eStateStopped:
            thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint)
            self.assertIsNotNone(thread)
            # Inspect at most 3 frames.
            numFrames = min(3, thread.GetNumFrames())
            for i in range(numFrames):
                frame = thread.GetFrameAtIndex(i)
                if self.TraceOn():
                    print("frame:", frame)

                name = frame.GetFunction().GetName()
                if name == "a":
                    callsOfA = callsOfA + 1

                # We'll inspect only the arguments for the current frame:
                #
                # arguments     => True
                # locals        => False
                # statics       => False
                # in_scope_only => True
                valList = frame.GetVariables(True, False, False, True)
                argList = []
                for val in valList:
                    argList.append(
                        "(%s)%s=%s" % (val.GetTypeName(), val.GetName(), val.GetValue())
                    )
                print("%s(%s)" % (name, ", ".join(argList)), file=session)

                # Also check the generic pc & stack pointer.  We can't test their absolute values,
                # but they should be valid.  Uses get_GPRs() from the lldbutil
                # module.
                gpr_reg_set = lldbutil.get_GPRs(frame)
                pc_value = gpr_reg_set.GetChildMemberWithName("pc")
                self.assertTrue(pc_value, "We should have a valid PC.")
                               
    
                # Make sure on arm targets we dont mismatch PC value on the basis of thumb bit.
                # Frame PC will not have thumb bit set in case of a thumb
                # instruction as PC.
                pc_value_int = int(pc_value.GetValue(), 0)
                if self.getArchitecture() in ["arm", "armv7", "armv7k"]:
                    pc_value_int &= ~1
                self.assertEqual(
                    pc_value_int,
                    frame.GetPC(),
                    "PC gotten as a value should equal frame's GetPC",
                )
                sp_value = gpr_reg_set.GetChildMemberWithName("sp")
                self.assertTrue(sp_value, "We should have a valid Stack Pointer.")
                self.assertEqual(
                    int(sp_value.GetValue(), 0),
                    frame.GetSP(),
                    "SP gotten as a value should equal frame's GetSP",
                )
                # Test that the "register" property's flat list matches the list from
                # the "registers" property that returns register sets:
                register_regs = set()
                flattened_regs = set()
                for reg_set in frame.registers:
                    for reg in reg_set:
                        flattened_regs.add(reg.name)
                for reg in frame.register:
                    register_regs.add(reg.name)
                self.assertEqual(register_regs, flattened_regs, "register matches registers")
                        
            print("---", file=session)
            process.Continue()

        # At this point, the inferior process should have exited.
        self.assertEqual(process.GetState(), lldb.eStateExited, PROCESS_EXITED)

        # Expect to find 'a' on the call stacks two times.
        self.assertEqual(callsOfA, 2, "Expect to find 'a' on the call stacks two times")
        # By design, the 'a' call frame has the following arg vals:
        #     o a((int)val=1, (char)ch='A')
        #     o a((int)val=3, (char)ch='A')
        if self.TraceOn():
            print("Full stack traces when stopped on the breakpoint 'c':")
            print(session.getvalue())
        self.expect(
            session.getvalue(),
            "Argument values displayed correctly",
            exe=False,
            substrs=["a((int)val=1, (char)ch='A')", "a((int)val=3, (char)ch='A')"],
        )

    def test_frame_api_boundary_condition(self):
        """Exercise SBFrame APIs with boundary condition inputs."""
        self.build()
        _, _, thread, _ = lldbutil.run_to_name_breakpoint(
            self, "c", bkpt_module="a.out"
        )

        frame = thread.GetFrameAtIndex(0)
        if self.TraceOn():
            print("frame:", frame)

        # Boundary condition testings.
        val1 = frame.FindVariable(None, True)
        val2 = frame.FindVariable(None, False)
        val3 = frame.FindValue(None, lldb.eValueTypeVariableGlobal)
        if self.TraceOn():
            print("val1:", val1)
            print("val2:", val2)

        frame.EvaluateExpression(None)

    def test_frame_api_IsEqual(self):
        """Exercise SBFrame API IsEqual."""
        self.build()
        _, _, thread, _ = lldbutil.run_to_name_breakpoint(
            self, "c", bkpt_module="a.out"
        )

        frameEntered = thread.GetFrameAtIndex(0)
        if self.TraceOn():
            print(frameEntered)
            lldbutil.print_stacktrace(thread)
        self.assertTrue(frameEntered)

        # Doing two step overs while still inside c().
        thread.StepOver()
        thread.StepOver()
        self.assertTrue(thread)
        frameNow = thread.GetFrameAtIndex(0)
        if self.TraceOn():
            print(frameNow)
            lldbutil.print_stacktrace(thread)
        self.assertTrue(frameNow)

        # The latest two frames are considered equal.
        self.assertTrue(frameEntered.IsEqual(frameNow))

        # Now let's step out of frame c().
        thread.StepOutOfFrame(frameNow)
        frameOutOfC = thread.GetFrameAtIndex(0)
        if self.TraceOn():
            print(frameOutOfC)
            lldbutil.print_stacktrace(thread)
        self.assertTrue(frameOutOfC)

        # The latest two frames should not be equal.
        self.assertFalse(frameOutOfC.IsEqual(frameNow))
