"""
Use lldb Python API to test dynamic values in ObjC
"""


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


class ObjCDynamicValueTestCase(TestBase):
    def setUp(self):
        # Call super's setUp().
        TestBase.setUp(self)

        # Find the line number to break for main.c.

        self.source_name = "dynamic-value.m"
        self.set_property_line = line_number(
            self.source_name,
            "// This is the line in setProperty, make sure we step to here.",
        )
        self.handle_SourceBase = line_number(
            self.source_name, "// Break here to check dynamic values."
        )
        self.main_before_setProperty_line = line_number(
            self.source_name, "// Break here to see if we can step into real method."
        )

    @add_test_categories(["pyapi"])
    @expectedFailureDarwin("llvm.org/pr20271 rdar://18684107")
    def test_get_objc_dynamic_vals(self):
        """Test fetching ObjC dynamic values."""
        if self.getArchitecture() == "i386":
            # rdar://problem/9946499
            self.skipTest("Dynamic types for ObjC V1 runtime not implemented")

        self.build()
        exe = self.getBuildArtifact("a.out")

        # Create a target from the debugger.

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

        # Set up our breakpoints:

        handle_SourceBase_bkpt = target.BreakpointCreateByLocation(
            self.source_name, self.handle_SourceBase
        )
        self.assertTrue(
            handle_SourceBase_bkpt and handle_SourceBase_bkpt.GetNumLocations() == 1,
            VALID_BREAKPOINT,
        )

        main_before_setProperty_bkpt = target.BreakpointCreateByLocation(
            self.source_name, self.main_before_setProperty_line
        )
        self.assertTrue(
            main_before_setProperty_bkpt
            and main_before_setProperty_bkpt.GetNumLocations() == 1,
            VALID_BREAKPOINT,
        )

        # Now launch the process, and do not stop at the entry point.
        process = target.LaunchSimple(None, None, self.get_process_working_directory())

        self.assertState(process.GetState(), lldb.eStateStopped, PROCESS_STOPPED)

        threads = lldbutil.get_threads_stopped_at_breakpoint(
            process, main_before_setProperty_bkpt
        )
        self.assertEqual(len(threads), 1)
        thread = threads[0]

        #
        #  At this point, myObserver has a Source pointer that is actually a KVO swizzled SourceDerived
        #  make sure we can get that properly:

        frame = thread.GetFrameAtIndex(0)
        myObserver = frame.FindVariable("myObserver", lldb.eDynamicCanRunTarget)
        self.assertTrue(myObserver)
        myObserver_source = myObserver.GetChildMemberWithName(
            "_source", lldb.eDynamicCanRunTarget
        )
        self.examine_SourceDerived_ptr(myObserver_source)

        #
        # Make sure a static value can be correctly turned into a dynamic
        # value.

        frame = thread.GetFrameAtIndex(0)
        myObserver_static = frame.FindVariable("myObserver", lldb.eNoDynamicValues)
        self.assertTrue(myObserver_static)
        myObserver = myObserver_static.GetDynamicValue(lldb.eDynamicCanRunTarget)
        myObserver_source = myObserver.GetChildMemberWithName(
            "_source", lldb.eDynamicCanRunTarget
        )
        self.examine_SourceDerived_ptr(myObserver_source)

        # The "frame var" code uses another path to get into children, so let's
        # make sure that works as well:

        result = lldb.SBCommandReturnObject()

        self.expect(
            "frame var -d run-target myObserver->_source",
            "frame var finds its way into a child member",
            patterns=["\(SourceDerived \*\)"],
        )

        # check that our ObjC GetISA() does a good job at hiding KVO swizzled
        # classes

        self.expect(
            "frame var -d run-target myObserver->_source -T",
            "the KVO-ed class is hidden",
            substrs=["SourceDerived"],
        )

        self.expect(
            "frame var -d run-target myObserver->_source -T",
            "the KVO-ed class is hidden",
            matching=False,
            substrs=["NSKVONotify"],
        )

        # This test is not entirely related to the main thrust of this test case, but since we're here,
        # try stepping into setProperty, and make sure we get into the version
        # in Source:

        thread.StepInto()

        threads = lldbutil.get_stopped_threads(process, lldb.eStopReasonPlanComplete)
        self.assertEqual(len(threads), 1)
        line_entry = threads[0].GetFrameAtIndex(0).GetLineEntry()

        self.assertEqual(line_entry.GetLine(), self.set_property_line)
        self.assertEqual(line_entry.GetFileSpec().GetFilename(), self.source_name)

        # Okay, back to the main business.  Continue to the handle_SourceBase
        # and make sure we get the correct dynamic value.

        threads = lldbutil.continue_to_breakpoint(process, handle_SourceBase_bkpt)
        self.assertEqual(len(threads), 1)
        thread = threads[0]

        frame = thread.GetFrameAtIndex(0)

        # Get "object" using FindVariable:

        noDynamic = lldb.eNoDynamicValues
        useDynamic = lldb.eDynamicCanRunTarget

        object_static = frame.FindVariable("object", noDynamic)
        object_dynamic = frame.FindVariable("object", useDynamic)

        # Delete this object to make sure that this doesn't cause havoc with
        # the dynamic object that depends on it.
        del object_static

        self.examine_SourceDerived_ptr(object_dynamic)

        # Get "this" using FindValue, make sure that works too:
        object_static = frame.FindValue(
            "object", lldb.eValueTypeVariableArgument, noDynamic
        )
        object_dynamic = frame.FindValue(
            "object", lldb.eValueTypeVariableArgument, useDynamic
        )
        del object_static
        self.examine_SourceDerived_ptr(object_dynamic)

        # Get "this" using the EvaluateExpression:
        object_static = frame.EvaluateExpression("object", noDynamic)
        object_dynamic = frame.EvaluateExpression("object", useDynamic)
        del object_static
        self.examine_SourceDerived_ptr(object_dynamic)

        # Continue again to the handle_SourceBase and make sure we get the correct dynamic value.
        # This one looks exactly the same, but in fact this is an "un-KVO'ed" version of SourceBase, so
        # its isa pointer points to SourceBase not NSKVOSourceBase or
        # whatever...

        threads = lldbutil.continue_to_breakpoint(process, handle_SourceBase_bkpt)
        self.assertEqual(len(threads), 1)
        thread = threads[0]

        frame = thread.GetFrameAtIndex(0)

        # Get "object" using FindVariable:

        object_static = frame.FindVariable("object", noDynamic)
        object_dynamic = frame.FindVariable("object", useDynamic)

        # Delete this object to make sure that this doesn't cause havoc with
        # the dynamic object that depends on it.
        del object_static

        self.examine_SourceDerived_ptr(object_dynamic)

    def examine_SourceDerived_ptr(self, object):
        self.assertTrue(object)
        self.assertNotEqual(object.GetTypeName().find("SourceDerived"), -1)
        derivedValue = object.GetChildMemberWithName("_derivedValue")
        self.assertTrue(derivedValue)
        self.assertEqual(int(derivedValue.GetValue(), 0), 30)
