#!/bin/sh
# Enveloppe graphique de « drop », appelée par les menus contextuels de bureau,
# sous Linux comme sous macOS.
#
# Elle n'ajoute qu'une chose au client : un retour visible. Lancé depuis un
# gestionnaire de fichiers, `drop` écrit sur une sortie standard que personne ne
# regarde — un envoi réussi et un envoi échoué se ressemblent alors beaucoup.
#
# Le même script sert sous Linux et sous macOS : seul le moyen d'afficher une
# notification change. osascript sur macOS, notify-send puis zenity sous Linux,
# la sortie d'erreur en dernier recours. Aucun des trois n'est une dépendance.
#
# Le repli se déclenche sur l'échec, pas sur l'absence : notify-send est souvent
# installé alors qu'aucun bus de session n'écoute — en SSH, dans un conteneur,
# sur une machine sans écran. Il sort alors en erreur, et se contenter de
# constater sa présence ferait disparaître le message.

set -eu

CLIENT=$(command -v drop || printf '%s' "$HOME/.local/bin/drop")

# Le texte est passé en arguments et non interpolé dans le source AppleScript :
# un nom de fichier contenant un guillemet couperait le script en deux.
signaler_macos() {
    if [ "$3" = 'critical' ]; then
        osascript - "$1" "$2" <<'FIN' >/dev/null 2>&1
on run argv
    display dialog (item 2 of argv) with title (item 1 of argv) ¬
        buttons {"Fermer"} default button 1 with icon stop
end run
FIN
    else
        osascript - "$1" "$2" <<'FIN' >/dev/null 2>&1
on run argv
    display notification (item 2 of argv) with title (item 1 of argv)
end run
FIN
    fi
}

signaler() {
    titre="$1"
    corps="$2"
    urgence="$3"

    if command -v osascript >/dev/null 2>&1 &&
       signaler_macos "$titre" "$corps" "$urgence"
    then
        return 0
    fi

    if command -v notify-send >/dev/null 2>&1 &&
       notify-send --app-name=Drop --icon=drop --urgency="$urgence" \
                   "$titre" "$corps" 2>/dev/null
    then
        return 0
    fi

    if command -v zenity >/dev/null 2>&1; then
        if [ "$urgence" = 'critical' ]; then
            zenity --error --title="$titre" --text="$corps" 2>/dev/null && return 0
        else
            zenity --notification --text="$titre : $corps" 2>/dev/null && return 0
        fi
    fi

    printf '%s : %s\n' "$titre" "$corps" >&2
}

case "${1:-}" in
    --aide|-h|--help|help|-\?)
        cat <<AIDE

  drop-envoyer — enveloppe graphique de « drop »

    drop-envoyer <fichier…>       envoie les fichiers, avec une notification
                                  système en retour (réussite comme échec)
    drop-envoyer --aide           affiche cette aide

  Appelée par les menus contextuels de bureau, sous Linux comme sous macOS.
  Elle n'ajoute au client qu'un retour visible : lancé depuis un gestionnaire
  de fichiers, « drop » écrit sur une sortie que personne ne regarde.

  Les dossiers sont refusés : Drop n'a pas d'arborescence, et envoyer leur
  contenu à plat serait une décision que personne n'a prise.

  Notification, par ordre d'essai : osascript (macOS), notify-send, zenity,
  puis la sortie d'erreur. Aucun des trois n'est une dépendance.

  Client utilisé : $CLIENT

AIDE
        exit 0
        ;;
esac

if [ ! -x "$CLIENT" ]; then
    signaler 'Drop' "Client introuvable. Installe-le avec integrations/linux/installer.sh" critical
    exit 1
fi

if [ $# -eq 0 ]; then
    signaler 'Drop' 'Aucun fichier sélectionné.' normal
    exit 0
fi

envoyes=0
echecs=0
dernier=''

for chemin in "$@"; do
    # Un dossier n'est pas un item : Drop n'a pas d'arborescence, et envoyer son
    # contenu à plat serait une décision que l'utilisateur n'a pas prise.
    if [ -d "$chemin" ]; then
        echecs=$((echecs + 1))
        dernier="les dossiers ne sont pas envoyés"
        continue
    fi

    if sortie=$("$CLIENT" "$chemin" 2>&1); then
        envoyes=$((envoyes + 1))
    else
        echecs=$((echecs + 1))
        dernier=$(printf '%s' "$sortie" | tail -n 1)
    fi
done

if [ "$echecs" -eq 0 ]; then
    signaler 'Drop' "$envoyes élément(s) envoyé(s)." normal
elif [ "$envoyes" -eq 0 ]; then
    signaler 'Drop — échec' "$dernier" critical
    exit 1
else
    signaler 'Drop — partiel' "$envoyes envoyé(s), $echecs en échec : $dernier" critical
fi
