import asyncio
from xdg import DesktopEntry
from pathlib import Path
import subprocess
import logging
import os
import gettext
import izvor_utils as izvor

_ = gettext.gettext


def _get_all_menu_entries():
    user_directories = [
        Path.home() / ".local/share/applications",
    ]

    system_directories = [
        Path("/usr/share/applications"),
        Path("/var/lib/flatpak/exports/share/applications/"),
        Path("/var/lib/snapd/desktop/applications"),
    ]

    if os.getenv("FLATPAK_SANDBOX_DIR"):
        system_directories = [Path("/run/host") / directory.relative_to("/") if str(directory).startswith("/usr/") else directory for directory in system_directories]

    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):
                    izvor.run_desktop_entry(str(desktop_file).removeprefix("/run/host"))

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