import unittest

import carb
import omni.kit.app
import omni.kit.test

# uncomment for dev work
# import unittest


class TestKitTest(omni.kit.test.AsyncTestCase):
    async def test_test_settings(self):
        # See [[test]] section
        carb.log_error("This message will not fail the test because it is excluded in [[test]]")
        self.assertEqual(carb.settings.get_settings().get("/extra_arg_passed/param"), 123)

    async def test_test_other_settings(self):
        self.assertEqual(carb.settings.get_settings().get("/extra_arg_passed/param"), 456)

    async def test_that_is_excluded(self):
        self.fail("Should not be called")

    async def test_get_test(self):
        if any("test_that_is_unreliable" in t.id() for t in omni.kit.test.get_tests()):
            self.skipTest("Skipping if test_that_is_unreliable ran")

        self.assertSetEqual(
            {t.id() for t in omni.kit.test.get_tests()},
            set(
                [
                    "omni.kit.test.tests.test_kit_test.TestKitTest.test_are_async",
                    "omni.kit.test.tests.test_kit_test.TestKitTest.test_can_be_skipped_1",
                    "omni.kit.test.tests.test_kit_test.TestKitTest.test_can_be_skipped_2",
                    "omni.kit.test.tests.test_kit_test.TestKitTest.test_can_be_sync",
                    "omni.kit.test.tests.test_kit_test.TestKitTest.test_get_test",
                    "omni.kit.test.tests.test_kit_test.TestKitTest.test_test_settings",
                    "omni.kit.test.tests.test_kit_test.TestKitTest.test_with_metadata",
                    "omni.kit.test.tests.test_kit_test.TestKitTest.test_with_subtest",
                    "omni.kit.test.tests.test_lookups.TestLookups.test_lookups",
                    "omni.kit.test.tests.test_nvdf.TestNVDF.test_convert_advanced_types",
                    "omni.kit.test.tests.test_nvdf.TestNVDF.test_convert_basic_types",
                    "omni.kit.test.tests.test_nvdf.TestNVDF.test_convert_reserved_types",
                    "omni.kit.test.tests.test_reporter.TestReporter.test_fail_report_data",
                    "omni.kit.test.tests.test_reporter.TestReporter.test_html_report",
                    "omni.kit.test.tests.test_reporter.TestReporter.test_success_report_data",
                    "omni.kit.test.tests.test_sampling.TestSampling.test_sampling_factor_one",
                    "omni.kit.test.tests.test_sampling.TestSampling.test_sampling_factor_point_five",
                    "omni.kit.test.tests.test_sampling.TestSampling.test_sampling_factor_zero",
                    "omni.kit.test.tests.test_sampling.TestSampling.test_with_fake_nvdf_query",
                ]
            ),
        )
        self.assertListEqual(
            [t.id() for t in omni.kit.test.get_tests(tests_filter="test_settings")],
            [
                "omni.kit.test.tests.test_kit_test.TestKitTest.test_test_settings",
            ],
        )

    async def test_are_async(self):
        app = omni.kit.app.get_app()
        update = app.get_update_number()
        await app.next_update_async()
        self.assertEqual(app.get_update_number(), update + 1)

    def test_can_be_sync(self):
        self.assertTrue(True)

    @unittest.skip("Skip test with @unittest.skip")
    async def test_can_be_skipped_1(self):
        self.assertTrue(False)

    async def test_can_be_skipped_2(self):
        self.skipTest("Skip test with self.skipTest")
        self.assertTrue(False)

    # subTest will get fixes in python 3.11, see https://bugs.python.org/issue25894
    async def test_with_subtest(self):
        with self.subTest(msg="subtest example"):
            self.assertTrue(True)

    async def test_with_metadata(self):
        """This is an example to use metadata"""
        print("##omni.kit.test[set, my_key, This line will be printed if the test fails]")
        self.assertTrue(True)

    async def test_that_is_unreliable(self):
        """This test will not run unless we run unreliable tests"""
        self.assertTrue(True)  # we don't make it fail when running unreliable tests

    # Development tests - uncomment when doing dev work to test all ways a test can succeed / fail
    # async def test_success(self):
    #     self.assertTrue(True)

    # async def test_fail_1(self):
    #     self.assertTrue(False)

    # async def test_fail_2(self):
    #     raise Exception("fuff")
    #     self.assertTrue(False)

    # will crash with stack overflow
    # async def test_fail_3(self):
    #     __import__("sys").setrecursionlimit(100000000)

    #     def crash():
    #         crash()
    #     crash()
