"""
Test lldb exception breakpoint command for CPP.
"""


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


class CPPBreakpointTestCase(TestBase):
    def setUp(self):
        # Call super's setUp().
        TestBase.setUp(self)
        self.source = "exceptions.cpp"
        self.catch_line = line_number(
            self.source, "// This is the line you should stop at for catch"
        )

    @expectedFailureAll(
        oslist=["windows"],
        bugnumber="llvm.org/pr24538, clang-cl does not support throw or catch",
    )
    def test(self):
        """Test lldb exception breakpoint command for CPP."""
        self.build()
        exe = self.getBuildArtifact("a.out")

        # Create a target from the debugger.

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

        exception_bkpt = target.BreakpointCreateForException(
            lldb.eLanguageTypeC_plus_plus, True, True
        )
        self.assertTrue(exception_bkpt, "Made an exception breakpoint")

        # Now run, and make sure we hit our breakpoint:
        process = target.LaunchSimple(None, None, self.get_process_working_directory())
        self.assertTrue(process, "Got a valid process")

        stopped_threads = []
        stopped_threads = lldbutil.get_threads_stopped_at_breakpoint(
            process, exception_bkpt
        )
        self.assertEqual(
            len(stopped_threads), 1, "Stopped at our exception breakpoint."
        )
        thread = stopped_threads[0]
        # Make sure our throw function is still above us on the stack:

        frame_functions = lldbutil.get_function_names(thread)
        self.assertEqual(
            frame_functions.count("throws_exception_on_even(int)"),
            1,
            "Our throw function is still on the stack.",
        )

        # Okay we hit our exception throw breakpoint, now make sure we get our catch breakpoint.
        # One potential complication is that we might hit a couple of the exception breakpoints in getting out of the throw.
        # so loop till we don't see the throws function on the stack.  We should stop one more time for our exception breakpoint
        # and that should be the catch...

        while frame_functions.count("throws_exception_on_even(int)") == 1:
            stopped_threads = lldbutil.continue_to_breakpoint(process, exception_bkpt)
            self.assertEqual(len(stopped_threads), 1)

            thread = stopped_threads[0]
            frame_functions = lldbutil.get_function_names(thread)

        self.assertEqual(
            frame_functions.count("throws_exception_on_even(int)"),
            0,
            "At catch our throw function is off the stack",
        )
        self.assertEqual(
            frame_functions.count("intervening_function(int)"),
            0,
            "At catch our intervening function is off the stack",
        )
        self.assertEqual(
            frame_functions.count("catches_exception(int)"),
            1,
            "At catch our catch function is on the stack",
        )
