import asyncio
from xdg import DesktopEntry
from pathlib import Path
import subprocess
import logging
from gi.repository import Gio
import os
import gettext
import izvor_utils as izvor

_ = gettext.gettext


def _get_all_menu_entries():
    if os.environ.get("XDG_DATA_HOME"):
        user_directories = [Path(dir).expanduser() / "applications" for dir in os.environ["XDG_DATA_HOME"].split(":")]
    else:
        user_directories = [
            Path.home() / ".local/share/applications",
        ]

    if os.environ.get("XDG_DATA_DIRS"):
        system_directories = [Path(dir) / "applications" for dir in os.environ["XDG_DATA_DIRS"].split(":")]
    else:
        system_directories = [
            Path("/usr/share/applications"),
            Path("/usr/local/share/applications"),
        ]

    directories = user_directories + system_directories

    for directory in directories:
        if directory.exists():
            for desktop_file in directory.glob("*.desktop"):
                entry = DesktopEntry.DesktopEntry(str(desktop_file))
                if entry.getHidden() or entry.getNoDisplay():
                    continue
                yield entry, desktop_file


def _match_query(entry: DesktopEntry, query: str):
    return (
        query.lower() in entry.getName().lower()
        or query.lower() in entry.getComment().lower()
        or query.lower() in entry.getExec().lower()
        or any(query.lower() in keyword.lower() for keyword in entry.getKeywords())
    )


class Provider(izvor.Provider):
    def __init__(self, config: dict):
        self.config = config
        self.name = _("Applications")
        self.icon = "applications-system"
        self.description = _("Search for installed applications on your device (the same you would find in your application menu).")

    async def search(self, query: str):
        for entry, desktop_file in _get_all_menu_entries():
            if _match_query(entry, query):
                def execute(desktop_file=desktop_file):
                    app_info = Gio.DesktopAppInfo.new_from_filename(str(desktop_file))
                    izvor.run_desktop_entry(app_info)

                yield {
                    "name": entry.getName() or desktop_file.stem,
                    "description": entry.getComment() or "",
                    "image": ("logo", entry.getIcon() or "application-x-executable"),
                    "execute": execute
                }
