from typing import List
import carb
import carb.settings
import omni.kit.app
import omni.ui as ui


from .style import ABOUT_STYLE


class AboutWidget:
    def __init__(self):
        app = omni.kit.app.get_app()
        self._app_info = f"{app.get_app_name()} {app.get_app_version()}"
        self._versions = self.__get_versions()
        plugins = [p for p in carb.get_framework().get_plugins() if p.impl.name]
        self._plugins = sorted(plugins, key=lambda x: x.impl.name)

        custom_image = carb.settings.get_settings().get("/app/window/imagePath")
        if custom_image:
            ABOUT_STYLE['About.Logo']['image_url'] = carb.tokens.get_tokens_interface().resolve(custom_image)

        self._frame = ui.Frame(build_fn=self._build_ui, style=ABOUT_STYLE)

    @property
    def app_info(self) -> List[str]:
        return self._app_info

    @app_info.setter
    def app_info(self, value: str) -> None:
        self._app_info = value
        with self._frame:
            self._frame.call_build_fn()

    @property
    def versions(self) -> List[str]:
        return [self._app_info] + self._versions

    @versions.setter
    def versions(self, values: List[str]) -> None:
        self._versions = values
        with self._frame:
            self._frame.call_build_fn()

    @property
    def plugins(self) -> list:
        return self._plugins

    @plugins.setter
    def plugins(self, values: list) -> None:
        self._plugins = values
        with self._frame:
            self._frame.call_build_fn()

    def _build_ui(self):
        with ui.VStack(spacing=5):
            with ui.ZStack(height=0):
                with ui.ZStack():
                    ui.Rectangle(style_type_name_override="About.Background.Fill")
                    ui.Image(
                        style_type_name_override="About.Background",
                        alignment=ui.Alignment.RIGHT_TOP,
                    )
                with ui.VStack():
                    ui.Spacer(height=10)
                    self.__build_app_info()
                    ui.Spacer(height=10)
                    for version_info in self._versions:
                        ui.Label(version_info, height=0, style_type_name_override="Text.Version")
                    ui.Spacer(height=10)
            ui.Spacer(height=0)
            ui.Label("Loaded plugins", height=0, style_type_name_override="Text.Title")
            ui.Line(height=0)
            with ui.ScrollingFrame(
                horizontal_scrollbar_policy=ui.ScrollBarPolicy.SCROLLBAR_ALWAYS_OFF,
                vertical_scrollbar_policy=ui.ScrollBarPolicy.SCROLLBAR_ALWAYS_ON,
            ):
                with ui.VStack(height=0, spacing=1):
                    for p in self._plugins:
                        ui.Label(f"{p.impl.name} {p.interfaces}", tooltip=p.libPath, style_type_name_override="Text.Plugin")

    def __build_app_info(self):
        with ui.HStack(height=0):
            ui.Spacer(width=10)
            with ui.ZStack(width=0, height=0):
                ui.Rectangle(style_type_name_override="Logo.Frame")
                with ui.HStack(height=0):
                    with ui.VStack():
                        ui.Spacer(height=5)
                        ui.Image(width=80, height=80, alignment=ui.Alignment.CENTER, style_type_name_override="About.Logo")
                        ui.Spacer(height=5)
                    with ui.VStack(width=0):
                        ui.Spacer(height=10)
                        ui.Line(alignment=ui.Alignment.LEFT, style_type_name_override="Logo.Separator")
                        ui.Spacer(height=18)
                    with ui.VStack(width=0, height=80):
                        ui.Spacer()
                        ui.Label("OMNIVERSE", style_type_name_override="Text.App")
                        ui.Label(self._app_info, style_type_name_override="Text.App")
                        ui.Spacer()
                    ui.Spacer()

    def __get_versions(self) -> List[str]:
        settings = carb.settings.get_settings()
        is_running_test = settings.get("/testconfig/isTest")
        # omni_usd_resolver isn't loaded until Ar.GetResolver is called.
        # In the ext test, nothing does that, so we need to do it
        # since the library isn't located in a PATH search entry.
        # Unforunately the ext is loaded before the test module runs,
        # so we can't do it there.
        try:
            if is_running_test:
                from pxr import Ar

                Ar.GetResolver()
            import omni.usd_resolver

            usd_resolver_version = omni.usd_resolver.get_version()
        except ImportError:
            usd_resolver_version = None

        try:
            import omni.usd_libs

            usd_version = omni.usd_libs.get_version()
        except ImportError:
            usd_version = None

        try:
            # OM-61509: Add MDL SDK and USD version in about window
            import omni.mdl.neuraylib
            from omni.mdl import pymdlsdk

            # get mdl sdk version
            neuraylib = omni.mdl.neuraylib.get_neuraylib()
            ineuray = neuraylib.getNeurayAPI()
            neuray = pymdlsdk.attach_ineuray(ineuray)
            # strip off the date and platform info and only keep the version and build info
            version = neuray.get_version().split(",")[:2]
            mdlsdk_version = ",".join(version)
        except ImportError:
            mdlsdk_version = None

        app = omni.kit.app.get_app()
        version_infos = [
            f"Omniverse Kit {app.get_kit_version()}",
            f"Client Library Version: {omni.client.get_version()}",
            f"USD Resolver Version: {usd_resolver_version}",
            f"USD Version: {usd_version}",
            f"MDL SDK Version: {mdlsdk_version}",
        ]

        return version_infos
