"""
Test that the built in ObjC exception throw recognizer works
"""

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


class TestObjCRecognizer(TestBase):
    NO_DEBUG_INFO_TESTCASE = True

    @skipUnlessDarwin
    def test_exception_recognizer_sub_class(self):
        """There can be many tests in a test case - describe this test here."""
        self.build()
        self.main_source_file = lldb.SBFileSpec("main.m")
        self.objc_recognizer_test(True)

    @skipUnlessDarwin
    def test_exception_recognizer_plain(self):
        """There can be many tests in a test case - describe this test here."""
        self.build()
        self.main_source_file = lldb.SBFileSpec("main.m")
        self.objc_recognizer_test(False)

    def objc_recognizer_test(self, sub_class):
        """Make sure we stop at the exception and get all the fields out of the recognizer.
        If sub_class is True, we make a subclass of NSException and throw that."""
        if sub_class:
            bkpt_string = "Set a breakpoint here for MyException"
        else:
            bkpt_string = "Set a breakpoint here for plain exception"

        (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(
            self, bkpt_string, self.main_source_file
        )

        # Now turn on the ObjC Exception breakpoint and continue to hit it:
        exception_bkpt = target.BreakpointCreateForException(
            lldb.eLanguageTypeObjC, False, True
        )
        self.assertGreater(
            exception_bkpt.GetNumLocations(), 0, "Got some exception locations"
        )

        threads = lldbutil.continue_to_breakpoint(process, exception_bkpt)
        self.assertEqual(len(threads), 1, "One thread hit exception breakpoint")
        frame = threads[0].frame[0]

        var_opts = lldb.SBVariablesOptions()
        var_opts.SetIncludeRecognizedArguments(True)
        var_opts.SetUseDynamic(True)
        vars = frame.GetVariables(var_opts)
        self.assertEqual(len(vars), 1, "Got the synthetic argument")
        self.assertTrue(vars[0].IsValid(), "Got a valid Exception variable")

        # This will be a pointer

        ns_exception_children = [
            ValueCheck(type="NSObject"),
            ValueCheck(name="name", summary='"NSException"'),
            ValueCheck(name="reason", summary='"Simple Reason"'),
            ValueCheck(name="userInfo"),
            ValueCheck(name="reserved"),
        ]
        ns_exception = ValueCheck(type="NSException", children=ns_exception_children)
        if not sub_class:
            simple_check = ValueCheck(name="exception", dereference=ns_exception)
            simple_check.check_value(self, vars[0], "Simple exception is right")
        else:
            my_exception_children = [
                ns_exception,
                ValueCheck(name="extra_info", type="int", value="100"),
            ]
            my_exception = ValueCheck(
                type="MyException", children=my_exception_children
            )
            sub_check = ValueCheck(
                name="exception", type="MyException *", dereference=my_exception
            )
            sub_check.check_value(self, vars[0], "Subclass exception is right")
