import omni.kit.test
import omni.graph.core as og
import omni.graph.core.tests as ogts
from omni.graph.core.tests.omnigraph_test_utils import _TestGraphAndNode
from omni.graph.core.tests.omnigraph_test_utils import _test_clear_scene
from omni.graph.core.tests.omnigraph_test_utils import _test_setup_scene
from omni.graph.core.tests.omnigraph_test_utils import _test_verify_scene


class TestOgn(ogts.OmniGraphTestCase):

    TEST_DATA = [
        {
            'outputs': [
                ['outputs:verify', True, False],
            ],
        },
    ]

    async def test_generated(self):
        test_info = _TestGraphAndNode()
        controller = og.Controller()
        for i, test_run in enumerate(self.TEST_DATA):
            await _test_clear_scene(self, test_run)
            test_info = await _test_setup_scene(self, controller, "/TestGraph", "TestNode_omni_graph_test_TestCppKeywords", "omni.graph.test.TestCppKeywords", test_run, test_info)
            await controller.evaluate(test_info.graph)
            _test_verify_scene(self, controller, test_run, test_info, f"omni.graph.test.TestCppKeywords User test case #{i+1}")

    async def test_vectorized_generated(self):
        test_info = _TestGraphAndNode()
        controller = og.Controller()
        for i, test_run in enumerate(self.TEST_DATA):
            await _test_clear_scene(self, test_run)
            test_info = await _test_setup_scene(self, controller, "/TestGraph", "TestNode_omni_graph_test_TestCppKeywords","omni.graph.test.TestCppKeywords", test_run, test_info, 16)
            await controller.evaluate(test_info.graph)
            _test_verify_scene(self, controller, test_run, test_info, f"omni.graph.test.TestCppKeywords User test case #{i+1}", 16)

    async def test_data_access(self):
        from omni.graph.test.ogn.OgnTestCppKeywordsDatabase import OgnTestCppKeywordsDatabase
        (_, (test_node,), _, _) = og.Controller.edit("/TestGraph", {
            og.Controller.Keys.CREATE_NODES: ("Template_omni_graph_test_TestCppKeywords", "omni.graph.test.TestCppKeywords")
        })
        database = OgnTestCppKeywordsDatabase(test_node)
        self.assertTrue(test_node.is_valid())
        node_type_name = test_node.get_type_name()
        self.assertEqual(og.GraphRegistry().get_node_type_version(node_type_name), 1)

        def _attr_error(attribute: og.Attribute, usd_test: bool) -> str:
            test_type = "USD Load" if usd_test else "Database Access"
            return f"{node_type_name} {test_type} Test - {attribute.get_name()} value error"


        self.assertTrue(test_node.get_attribute_exists("inputs:atomic_cancel"))
        attribute = test_node.get_attribute("inputs:atomic_cancel")
        db_value = database.inputs.atomic_cancel
        expected_value = 0.0
        ogts.verify_values(expected_value, db_value, _attr_error(attribute, False))

        self.assertTrue(test_node.get_attribute_exists("inputs:atomic_commit"))
        attribute = test_node.get_attribute("inputs:atomic_commit")
        db_value = database.inputs.atomic_commit
        expected_value = 0.0
        ogts.verify_values(expected_value, db_value, _attr_error(attribute, False))

        self.assertTrue(test_node.get_attribute_exists("inputs:atomic_noexcept"))
        attribute = test_node.get_attribute("inputs:atomic_noexcept")
        db_value = database.inputs.atomic_noexcept
        expected_value = 0.0
        ogts.verify_values(expected_value, db_value, _attr_error(attribute, False))

        self.assertTrue(test_node.get_attribute_exists("inputs:consteval"))
        attribute = test_node.get_attribute("inputs:consteval")
        db_value = database.inputs.consteval
        expected_value = 0.0
        ogts.verify_values(expected_value, db_value, _attr_error(attribute, False))

        self.assertTrue(test_node.get_attribute_exists("inputs:constinit"))
        attribute = test_node.get_attribute("inputs:constinit")
        db_value = database.inputs.constinit
        expected_value = 0.0
        ogts.verify_values(expected_value, db_value, _attr_error(attribute, False))

        self.assertTrue(test_node.get_attribute_exists("inputs:reflexpr"))
        attribute = test_node.get_attribute("inputs:reflexpr")
        db_value = database.inputs.reflexpr
        expected_value = 0.0
        ogts.verify_values(expected_value, db_value, _attr_error(attribute, False))

        self.assertTrue(test_node.get_attribute_exists("inputs:requires"))
        attribute = test_node.get_attribute("inputs:requires")
        db_value = database.inputs.requires
        expected_value = 0.0
        ogts.verify_values(expected_value, db_value, _attr_error(attribute, False))

        self.assertTrue(test_node.get_attribute_exists("outputs:verify"))
        attribute = test_node.get_attribute("outputs:verify")
        db_value = database.outputs.verify
