"""
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 as well as llvm-gcc.


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"]
        )
