# Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
#
# NVIDIA CORPORATION and its licensors retain all intellectual property
# and proprietary rights in and to this software, related documentation
# and any modifications thereto.  Any use, reproduction, disclosure or
# distribution of this software and related documentation without an express
# license agreement from NVIDIA CORPORATION is strictly prohibited.
#

__all__ = ["validate_extensions_tests"]

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


EXCLUSION_LIST = []


def validate_extensions_tests(exclusion_list=[]):
    """Return the number of enabled extensions without python tests"""
    failures = []
    EXCLUSION_LIST.extend(exclusion_list)
    settings = carb.settings.get_settings()
    manager = omni.kit.app.get_app().get_extension_manager()
    for ext in manager.get_extensions():
        ext_id = ext["id"]
        ext_name = ext["name"]
        info = manager.get_extension_dict(ext_id)

        # No apps
        if info.get("isKitFile", False):
            print(f"[ ok ] {ext_name} is an app")
            continue

        # Exclusion list
        if ext_name in EXCLUSION_LIST:
            print(f"[ ok ] {ext_name} is in the exclusion list")
            continue

        waiver = False
        reason = ""
        cpp_tests = False
        test_info = info.get("test", None)
        if isinstance(test_info, list) or isinstance(test_info, tuple):
            for t in test_info:
                if "waiver" in t:
                    reason = t.get("waiver", "")
                    waiver = True
                if "cppTests" in t:
                    cpp_tests = True

        if waiver:
            print(f"[ ok ] {ext_name} has a waiver: {reason}")
            continue

        enabled = ext.get("enabled", False)
        if not enabled:
            print(f"[ ok ] {ext_name} is not enabled")
            continue

        # another test will report that the extension failed to load
        failed = info.get("state/failed", False)
        if failed:
            print(f"[ !! ] {ext_name} failed to load")
            continue

        include_tests = []
        python_dict = info.get("python", {})
        python_modules = python_dict.get("module", []) + python_dict.get("modules", [])
        for m in python_modules:
            module = m.get("name")
            if module:
                include_tests.append("{}.*".format(module))
        settings.set("/exts/omni.kit.test/includeTests", include_tests)

        print(f"[ .. ] {ext_name} get tests...")
        test_count = omni.kit.test.get_tests()
        if len(test_count) > 0:
            print(f"[ ok ] {ext_name} has {len(test_count)} tests")
        elif cpp_tests:
            print(f"[ ok ] {ext_name} has cpp tests")
        else:
            failures.append(ext_name)
            print(f"[fail] {ext_name} has {len(test_count)} tests")

    if len(failures) == 0:
        print("\n[success] All extensions have tests or waiver!\n")
    else:
        print("")
        print(f"[error] Found {len(failures)} extensions without tests or waiver:")
        for count, ext in enumerate(failures):
            print(f"  {count+1}: {ext}")
        print("")
    return len(failures)


if __name__ == "__main__":
    result = validate_extensions_tests()
    omni.kit.app.get_app().post_quit(result)
