#!/usr/bin/env python3
"""List launchers using desktop-entry translations for the selected UI language."""
import configparser
import json
import os
from pathlib import Path
import re
import sys


def launchers(directories, language, structured=False):
    language = language.split('.')[0].replace('-', '_')
    keys = ['Name[' + language + ']', 'Name[' + language.split('_')[0] + ']', 'Name']
    seen = set()
    seen_commands = set()
    result = []
    for directory in directories:
        if not directory.is_dir():
            continue
        for path in sorted(directory.rglob('*.desktop')):
            identity = str(path.relative_to(directory)).replace('/', '-')
            if identity in seen:
                continue
            seen.add(identity)
            parser = configparser.ConfigParser(interpolation=None, strict=False)
            parser.optionxform = str
            try:
                parser.read_string(path.read_text())
                entry = parser['Desktop Entry']
                if entry.get('Type', 'Application') != 'Application' or any(entry.get(k, '').lower() == 'true' for k in ['NoDisplay', 'Hidden']):
                    continue
                name = next((entry[k] for k in keys if entry.get(k)), '')
                command = re.sub(r'\s+%[a-zA-Z](?=\s|$)', '', entry.get('Exec', ''))
                row = (name, command, entry.get('Icon', ''))
                if name and command and all(not any(c in field for c in '|\n\r') for field in row):
                    # Two desktop IDs can launch the same application (for
                    # example webapp-manager in two applications directories).
                    # The first directory has precedence, just as for IDs.
                    if command in seen_commands:
                        continue
                    seen_commands.add(command)
                    names = sorted({value for key, value in entry.items() if key == 'Name' or key.startswith('Name[')})
                    result.append({'id': identity, 'desktopPath': str(path), 'name': name, 'cmd': command, 'icon': row[2], 'names': names} if structured else '|'.join(row))
            except (OSError, UnicodeError, configparser.Error, KeyError):
                continue
    if structured:
        return sorted(result, key=lambda item: item['name'].casefold())
    return sorted(set(result), key=str.casefold)


def main():
    home = Path.home()
    data_home = Path(os.environ.get('XDG_DATA_HOME', home / '.local/share'))
    directories = [data_home / 'applications']
    directories += [Path(p) / 'applications' for p in os.environ.get('XDG_DATA_DIRS', '/usr/local/share:/usr/share').split(':') if p]
    directories += [home / '.local/share/flatpak/exports/share/applications', Path('/var/lib/flatpak/exports/share/applications')]
    directories += list((home / '.var/app').glob('*/share/applications'))
    directories += list(Path('/snap').glob('*/current/meta/gui'))
    structured = '--json' in sys.argv[1:]
    arguments = [value for value in sys.argv[1:] if value != '--json']
    rows = launchers(directories, arguments[0] if arguments else os.environ.get('LANG', 'en'), structured)
    print(json.dumps(rows, ensure_ascii=False) if structured else '\n'.join(rows))


if __name__ == '__main__':
    main()
