import os
from functools import lru_cache
from typing import List, Optional

import omni.kit.app
import omni.ui as ui

ext_manager = None


# Sync only once for now
@lru_cache()
def _sync_registry():
    ext_manager.refresh_registry()


@lru_cache()
def get_extpath_git_ext():
    try:
        import omni.kit.extpath.git as git_ext

        return git_ext
    except ImportError:
        return None

class ExtensionItem(ui.AbstractItem):
    def __init__(self, ext_info: dict):
        super().__init__()
        self.name = ext_info.get("fullname")
        enabled_version = ext_info.get("enabled_version")
        self.enabled_id = enabled_version.get("id")
        self.version = self.__get_version(self.enabled_id)
        latest_version = ext_info.get("latest_version")
        self.latest_id = latest_version.get("id")

        self.flags = ext_info.get("flags")
        self.enabled = bool(self.flags & omni.ext.EXTENSION_SUMMARY_FLAG_ANY_ENABLED)

        ext_info_local = ext_manager.get_extension_dict(self.enabled_id)
        self.path = ext_info_local.get("path", "")
        package_dict = ext_info_local.get("package", {})
        self.icon = self.__get_icon(package_dict)
        self.description = package_dict.get("description", "") or "No Description"

    def __get_version(self, ext_id: str) -> str:
        """Convert 'omni.foo-tag-1.2.3' to '1.2.3'"""
        a, b, *_ = ext_id.split("-") + [""]
        if b and b[0:1].isdigit():
            return f"{b}"
        return ""

    def __get_icon(self, package_dict: dict) -> str:
        path = package_dict.get("icon", None)
        if path:
            icon_path = os.path.join(self.path, path)
            if os.path.exists(icon_path):
                return icon_path
        return ""

class ExtensionsModel(ui.AbstractItemModel):
    def __init__(self):
        super().__init__()
        self._items: List[ExtensionItem] = []

        global ext_manager
        app = omni.kit.app.get_app()
        ext_manager = app.get_extension_manager()

        self.refresh()

    def get_item_children(self, item: Optional[ExtensionItem]) -> List[ExtensionItem]:
        return self._items

    def refresh(self):
        # Refresh exts (comes from omni.kit.window.extensions)
        get_extpath_git_ext.cache_clear()
        _sync_registry()

        ext_summaries = ext_manager.fetch_extension_summaries()
        updates_exts = [
            ext for ext in ext_summaries if ext["enabled_version"]["id"] and ext["enabled_version"]["id"] != ext["latest_version"]["id"]
        ]

        self._items = [ExtensionItem(ext) for ext in updates_exts]
