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

from __future__ import print_function


import os
import time
import re
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):

    mydir = TestBase.compute_mydir(__file__)

    @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()

    @expectedFailureAll(
        oslist=["windows"],
        bugnumber="llvm.org/pr26265: args in frames other than #0 are not evaluated correctly")
    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.assertTrue(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.assertTrue(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.assertTrue(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"])
