"""
Test conditionally break on a function and inspect its variables.
"""

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

# rdar://problem/8532131
# lldb not able to digest the clang-generated debug info correctly with respect to function name
#
# This class currently fails for clang.


class ConditionalBreakTestCase(TestBase):
    @add_test_categories(["pyapi"])
    def test_with_python(self):
        """Exercise some thread and frame APIs to break if c() is called by a()."""
        self.build()
        self.do_conditional_break()

    def test_with_command(self):
        """Simulate a user using lldb commands to break on c() if called from a()."""
        self.build()
        self.simulate_conditional_break_by_user()

    def do_conditional_break(self):
        """Exercise some thread and frame APIs to break if c() is called by a()."""
        exe = self.getBuildArtifact("a.out")

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

        breakpoint = target.BreakpointCreateByName("c", exe)
        self.assertTrue(breakpoint, VALID_BREAKPOINT)

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

        self.assertTrue(process, PROCESS_IS_VALID)

        # The stop reason of the thread should be breakpoint.
        self.assertState(
            process.GetState(), lldb.eStateStopped, STOPPED_DUE_TO_BREAKPOINT
        )

        # Find the line number where a's parent frame function is c.
        line = line_number(
            "main.c", "// Find the line number where c's parent frame is a here."
        )

        # Suppose we are only interested in the call scenario where c()'s
        # immediate caller is a() and we want to find out the value passed from
        # a().
        #
        # The 10 in range(10) is just an arbitrary number, which means we would
        # like to try for at most 10 times.
        for j in range(10):
            if self.TraceOn():
                print("j is: ", j)
            thread = lldbutil.get_one_thread_stopped_at_breakpoint(process, breakpoint)
            self.assertIsNotNone(
                thread, "Expected one thread to be stopped at the breakpoint"
            )

            if thread.GetNumFrames() >= 2:
                frame0 = thread.GetFrameAtIndex(0)
                name0 = frame0.GetFunction().GetName()
                frame1 = thread.GetFrameAtIndex(1)
                name1 = frame1.GetFunction().GetName()
                # lldbutil.print_stacktrace(thread)
                self.assertEqual(name0, "c", "Break on function c()")
                if name1 == "a":
                    # By design, we know that a() calls c() only from main.c:27.
                    # In reality, similar logic can be used to find out the call
                    # site.
                    self.assertEqual(
                        frame1.GetLineEntry().GetLine(),
                        line,
                        "Immediate caller a() at main.c:%d" % line,
                    )

                    # And the local variable 'val' should have a value of (int)
                    # 3.
                    val = frame1.FindVariable("val")
                    self.assertEqual("int", val.GetTypeName())
                    self.assertEqual("3", val.GetValue())
                    break

            process.Continue()

    def simulate_conditional_break_by_user(self):
        """Simulate a user using lldb commands to break on c() if called from a()."""

        # Sourcing .lldb in the current working directory, which sets the main
        # executable, sets the breakpoint on c(), and adds the callback for the
        # breakpoint such that lldb only stops when the caller of c() is a().
        # the "my" package that defines the date() function.
        if self.TraceOn():
            print("About to source .lldb")

        if not self.TraceOn():
            self.HideStdout()

        # Separate out the "file " + self.getBuildArtifact("a.out") command from .lldb file, for the sake of
        # remote testsuite.
        self.runCmd("file " + self.getBuildArtifact("a.out"))
        self.runCmd("command source .lldb")

        self.runCmd("break list")

        if self.TraceOn():
            print("About to run.")
        self.runCmd("run", RUN_SUCCEEDED)

        self.runCmd("break list")

        if self.TraceOn():
            print("Done running")

        # The stop reason of the thread should be breakpoint.
        self.expect(
            "thread list",
            STOPPED_DUE_TO_BREAKPOINT,
            substrs=["stopped", "stop reason = breakpoint"],
        )

        # The frame info for frame #0 points to a.out`c and its immediate caller
        # (frame #1) points to a.out`a.

        self.expect("frame info", "We should stop at c()", substrs=["a.out`c"])

        # Select our parent frame as the current frame.
        self.runCmd("frame select 1")
        self.expect(
            "frame info", "The immediate caller should be a()", substrs=["a.out`a"]
        )
