#!/usr/bin/env python3
"""The single registry powering both ls -rr and -rr APP NAME."""
import configparser
from collections import Counter
import os
from pathlib import Path
import subprocess
import sys


def applications():
    home = Path.home()
    xdg_dirs = os.environ.get('XDG_DATA_DIRS', '/usr/local/share:/usr/share').split(':')
    extra = ['/var/lib/flatpak/exports/share', str(home / '.local/share/flatpak/exports/share'), '/var/lib/snapd/desktop']
    roots = [home / '.local/share/applications'] + [Path(d) / 'applications' for d in xdg_dirs + extra if d]
    seen = set()
    apps = []
    for root in roots:
        if not root.is_dir():
            continue
        for path in sorted(root.rglob('*.desktop')):
            desktop_id = str(path.relative_to(root)).replace('/', '-')
            if desktop_id in seen:
                continue
            seen.add(desktop_id)
            cfg = configparser.ConfigParser(interpolation=None, strict=False)
            cfg.optionxform = str
            try:
                cfg.read(path, encoding='utf-8')
                section = cfg['Desktop Entry']
                if section.get('Type') != 'Application' or section.get('Hidden', '').lower() == 'true':
                    continue
                if not (section.get('Exec') or section.get('DBusActivatable', '').lower() == 'true'):
                    continue
                name = section.get('Name', path.stem).strip()
                if not name:
                    continue
                apps.append({'name': name, 'id': desktop_id})
            except (OSError, ValueError, configparser.Error, KeyError):
                pass
    counts = Counter(a['name'].casefold() for a in apps)
    for app in apps:
        app['label'] = app['name'] if counts[app['name'].casefold()] == 1 else f"{app['name']} [{app['id']}]"
    return sorted(apps, key=lambda a: (a['name'].casefold(), a['id']))


def main():
    apps = applications()
    args = sys.argv[1:]
    if args == ['--list']:
        for app in apps:
            print(app['label'])
        print(f'\n{len(apps)} applications available via -rr')
        return 0
    if not args or args == ['--help']:
        print('Usage: ls -rr  |  -rr APPLICATION NAME')
        return 0
    query = ' '.join(args).strip().casefold()
    matches = [a for a in apps if a['label'].casefold() == query or a['id'].casefold() == query]
    if not matches:
        matches = [a for a in apps if a['name'].casefold() == query]
    if not matches:
        matches = [a for a in apps if a['name'].casefold().startswith(query)]
    if not matches:
        print('Application not found. Type ls -rr for the exact launchable names.', file=sys.stderr)
        return 1
    if len(matches) > 1:
        print('More than one application matches. Use an exact name from ls -rr:', file=sys.stderr)
        for a in matches:
            print('  ' + a['label'], file=sys.stderr)
        return 2
    app = matches[0]
    try:
        subprocess.Popen(
            ['gtk-launch', app['id']],
            stdin=subprocess.DEVNULL,
            stdout=subprocess.DEVNULL,
            stderr=subprocess.DEVNULL,
            start_new_session=True,
            close_fds=True,
        )
    except OSError as exc:
        print(f"Could not start {app['label']}: {exc}", file=sys.stderr)
        return 1
    print(f"Launching {app['label']}... (terminal ready)")
    return 0


if __name__ == '__main__':
    raise SystemExit(main())
