"""
Test that you can set breakpoint and hit the C++ language exception breakpoint
"""


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


@requireNotWasm("wasm inferiors are built with -fno-exceptions")
class TestCPPExceptionBreakpoint(TestBase):
    my_var = 10

    @add_test_categories(["pyapi"])
    @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24538")
    def test_cpp_exception_breakpoint(self):
        """Test setting and hitting the C++ exception breakpoint."""
        self.build()
        self.do_cpp_exception_bkpt()

    @add_test_categories(["pyapi"])
    @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24538")
    def test_dummy_target_cpp_exception_breakpoint(self):
        """Test setting and hitting the C++ exception breakpoint from dummy target."""
        self.build()
        self.do_dummy_target_cpp_exception_bkpt()

    def setUp(self):
        TestBase.setUp(self)
        self.main_source = "main.c"
        self.main_source_spec = lldb.SBFileSpec(self.main_source)

    def do_cpp_exception_bkpt(self):
        exe = self.getBuildArtifact("a.out")
        error = lldb.SBError()

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

        exception_bkpt = self.target.BreakpointCreateForException(
            lldb.eLanguageTypeC_plus_plus, False, True
        )
        self.assertTrue(exception_bkpt.IsValid(), "Created exception breakpoint.")

        process = self.target.LaunchSimple(
            None, None, self.get_process_working_directory()
        )
        self.assertTrue(process, PROCESS_IS_VALID)

        thread_list = lldbutil.get_threads_stopped_at_breakpoint(
            process, exception_bkpt
        )
        self.assertEqual(
            len(thread_list), 1, "One thread stopped at the exception breakpoint."
        )

    def do_dummy_target_cpp_exception_bkpt(self):
        exe = self.getBuildArtifact("a.out")
        error = lldb.SBError()

        dummy_exception_bkpt = self.dbg.GetDummyTarget().BreakpointCreateForException(
            lldb.eLanguageTypeC_plus_plus, False, True
        )
        self.assertTrue(
            dummy_exception_bkpt.IsValid(),
            "Created exception breakpoint in dummy target.",
        )

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

        exception_bkpt = self.target.GetBreakpointAtIndex(0)
        self.assertTrue(
            exception_bkpt.IsValid(),
            "Target primed with exception breakpoint from dummy target.",
        )

        process = self.target.LaunchSimple(
            None, None, self.get_process_working_directory()
        )
        self.assertTrue(process, PROCESS_IS_VALID)

        thread_list = lldbutil.get_threads_stopped_at_breakpoint(
            process, exception_bkpt
        )
        self.assertEqual(
            len(thread_list), 1, "One thread stopped at the exception breakpoint."
        )
