#!/usr/bin/env bash

CACHE_DIR="/tmp/qs_launcher"

DRUN_CACHE="$CACHE_DIR/drun.txt"
RUN_CACHE="$CACHE_DIR/run.txt"

mkdir -p "$CACHE_DIR"


get_desktop_files() {
    IFS=':' read -ra DIRS <<< \
        "${XDG_DATA_DIRS:-/usr/local/share:/usr/share}"

    for dir in "${DIRS[@]}"; do
        APP_DIR="$dir/applications"

        [ -d "$APP_DIR" ] || continue

        find "$APP_DIR" \
            -maxdepth 1 \
            -name "*.desktop" \
            2>/dev/null
    done | while read -r f; do

        name=$(
            grep -m1 '^Name=' "$f" \
            | cut -d= -f2-
        )

        exec=$(
            grep -m1 '^Exec=' "$f" \
            | cut -d= -f2- \
            | sed 's/%[fFuUik]//g'
        )

        type=$(
            grep -m1 '^Type=' "$f" \
            | cut -d= -f2-
        )

        nodisplay=$(
            grep -m1 '^NoDisplay=' "$f" \
            | cut -d= -f2- \
            | tr '[:upper:]' '[:lower:]'
        )

        icon=$(
            grep -m1 '^Icon=' "$f" \
            | cut -d= -f2-
        )

        [[ "$type" == "Application" ]] || continue
        [[ "$nodisplay" != "true" ]] || continue
        [[ -n "$name" ]] || continue

        printf "%s\t%s\t%s\t%s\n" \
            "$name" \
            "$exec" \
            "$(basename "$f" .desktop)" \
            "$icon"
    done
}


get_binaries() {
    compgen -c \
        | sort -u \
        | head -600 \
        | awk '{
            print $1 "\t" $1 "\t" $1
        }'
}


sort_and_dedup() {
    sort -f -t$'\t' -k1,1 \
        | awk -F'\t' '!seen[$1]++'
}


build_drun() {
    get_desktop_files | sort_and_dedup
}

build_run() {
    { get_desktop_files; get_binaries; } | sort_and_dedup
}


update_cache() {
    build_drun > "$DRUN_CACHE.tmp"
    build_run  > "$RUN_CACHE.tmp"

    mv "$DRUN_CACHE.tmp" "$DRUN_CACHE"
    mv "$RUN_CACHE.tmp"  "$RUN_CACHE"
}


if [ "$1" == "--update-only" ]; then
    update_cache
    exit 0
fi
