"""Tests reparenting workflows"""

import omni.graph.core as og
import omni.graph.core.tests as ogts


# ======================================================================
class TestRewireExecInput(ogts.OmniGraphTestCase):
    """Run tests that exercises execution of nodes after various connection and disconnection of attributes."""

    async def test_rewire_exec_input_from_same_named_outputs(self):
        """Test making a 2nd connection to an exec input already connected to at upstream attrib of the same name."""

        # Load the test scene which has:
        #   OnImpulse (A1) node --> (A) input of ExpectInputEnabledTest node: output (A) --> Counter (A) node.
        #   OnImpulse (A2) node --> (no connections)
        #   OnImpulse (B) node --> (B) input of same ExpectInputEnabledTestnode: output (B) --> Counter (B) node.
        (result, error) = await ogts.load_test_file("TestRewireExecInput.usda", use_caller_subdirectory=True)
        self.assertTrue(result, error)

        impulse_a_1 = "/World/ActionGraph/on_impulse_event_A1"
        impulse_a_2 = "/World/ActionGraph/on_impulse_event_A2"
        impulse_b = "/World/ActionGraph/on_impulse_event_B"
        counter_a = "/World/ActionGraph/counter_A"
        counter_b = "/World/ActionGraph/counter_B"
        exec_test_input_a = "/World/ActionGraph/execinputenabledtest.inputs:execInA"

        # Ensure initial state

        # Ensure the counters starts at 0
        self.assertEqual(og.Controller.get(og.Controller.attribute("state:count", counter_a)), 0)
        self.assertEqual(og.Controller.get(og.Controller.attribute("state:count", counter_b)), 0)

        # Trigger impulse A1 and verify counters are (A) 1, (B) 0
        og.Controller.set(og.Controller.attribute("state:enableImpulse", impulse_a_1), True)
        await og.Controller.evaluate()
        self.assertEqual(og.Controller.get(og.Controller.attribute("state:count", counter_a)), 1)
        self.assertEqual(og.Controller.get(og.Controller.attribute("state:count", counter_b)), 0)

        # Trigger impulse B and verify counters are (A) 1, (B) 1
        og.Controller.set(og.Controller.attribute("state:enableImpulse", impulse_b), True)
        await og.Controller.evaluate()
        self.assertEqual(og.Controller.get(og.Controller.attribute("state:count", counter_a)), 1)
        self.assertEqual(og.Controller.get(og.Controller.attribute("state:count", counter_b)), 1)

        # Reconnect wires

        # Connect OnImpulse A2 to the same (A) input of ExecInputEnabledTest node while OnImpulse A1 is still
        # connected to it
        keys = og.Controller.Keys
        og.Controller.edit(
            "/World/ActionGraph", {keys.CONNECT: [(impulse_a_2 + ".outputs:execOut", exec_test_input_a)]}
        )

        # Disconnect impulse A1 from the ExecInputEnabledTest node. This could have been done in 1 call to .edit()
        # but this order very much matters for this bug https://nvidia-omniverse.atlassian.net/browse/OM-51679
        # so extra explicitly ordering the operations for this test
        og.Controller.edit(
            "/World/ActionGraph", {keys.DISCONNECT: [(impulse_a_1 + ".outputs:execOut", exec_test_input_a)]}
        )

        # Validate the fix for ExecInputEnabledTest's (A) input being set to active

        # Trigger impulse A2 and verify counters are (A) 2, (B) 1
        og.Controller.set(og.Controller.attribute("state:enableImpulse", impulse_a_2), True)
        await og.Controller.evaluate()
        self.assertEqual(og.Controller.get(og.Controller.attribute("state:count", counter_a)), 2)
        self.assertEqual(og.Controller.get(og.Controller.attribute("state:count", counter_b)), 1)

        # Validate that (A) input is deactive such that (B) input still works

        # Trigger impulse B and verify counters are (A) 2, (B) 2
        og.Controller.set(og.Controller.attribute("state:enableImpulse", impulse_b), True)
        await og.Controller.evaluate()
        self.assertEqual(og.Controller.get(og.Controller.attribute("state:count", counter_a)), 2)
        self.assertEqual(og.Controller.get(og.Controller.attribute("state:count", counter_b)), 2)
