#!/bin/sh
# Installe Async Herald, l'app de bureau, sur Linux, sans sudo :
#
#   curl -fsSL https://herald.codes/install.sh | sh
#
# Télécharge l'AppImage de la dernière version publiée, vérifie son empreinte
# SHA-256, l'installe dans ~/.local/share/async-herald, ajoute la commande
# `herald` (~/.local/bin) et une entrée dans le menu des applications.
# Relancer la commande met l'app à jour.
#
# Désinstaller :  curl -fsSL https://herald.codes/install.sh | sh -s -- --uninstall
set -eu

API="${HERALD_API:-https://api.herald.codes}"
SITE="https://herald.codes"
DATA="${XDG_DATA_HOME:-$HOME/.local/share}"
APP_DIR="$DATA/async-herald"
APP="$APP_DIR/Async-Herald.AppImage"
BIN_DIR="${HERALD_BIN_DIR:-$HOME/.local/bin}"
BIN="$BIN_DIR/herald"
DESKTOP="$DATA/applications/async-herald.desktop"
ICON="$DATA/icons/hicolor/256x256/apps/async-herald.png"

say() { printf '%s\n' "$*"; }
fail() { printf 'Erreur : %s\n' "$*" >&2; exit 1; }

if [ "${1:-}" = "--uninstall" ]; then
    rm -f "$BIN" "$DESKTOP" "$ICON"
    rm -rf "$APP_DIR"
    say "Async Herald est désinstallé. Vos données locales restent dans ~/.local/share/fr.itsasync.herald.desktop."
    exit 0
fi

[ "$(uname -s)" = "Linux" ] || fail "ce script est pour Linux. Sur Mac : brew install async-herald/tap/herald ; sur Windows : $SITE/downloads"

case "$(uname -m)" in
    x86_64 | amd64) ARCH="x86_64" ;;
    aarch64 | arm64) ARCH="aarch64" ;;
    *) fail "processeur $(uname -m) non pris en charge (x86_64 ou aarch64 uniquement)." ;;
esac

if command -v curl >/dev/null 2>&1; then
    fetch() { curl -fsSL "$1"; }
    download() { curl -fL --progress-bar -o "$2" "$1"; }
elif command -v wget >/dev/null 2>&1; then
    fetch() { wget -qO- "$1"; }
    download() { wget -qO "$2" "$1"; }
else
    fail "curl ou wget est nécessaire."
fi

if command -v sha256sum >/dev/null 2>&1; then
    sha256() { sha256sum "$1" | cut -d' ' -f1; }
elif command -v shasum >/dev/null 2>&1; then
    sha256() { shasum -a 256 "$1" | cut -d' ' -f1; }
else
    fail "sha256sum est nécessaire pour vérifier le fichier."
fi

# Dernière version Linux publiée : {"version":"…","downloadUrl":"…","sha256":"…",…}
JSON="$(fetch "$API/heralds/desktop/latest?platform=linux")" || fail "impossible de joindre $API."
field() { printf '%s' "$JSON" | tr -d '\n' | sed -n "s/.*\"$1\":\"\([^\"]*\)\".*/\1/p"; }
VERSION="$(field version)"
URL="$(field downloadUrl)"
SHA="$(field sha256)"
[ -n "$VERSION" ] && [ -n "$URL" ] || fail "aucune version Linux publiée pour l'instant. Voir $SITE/downloads"

# La version publiée est l'AppImage x86_64 ; la version ARM porte le même nom
# avec aarch64, sans empreinte publiée.
if [ "$ARCH" = "aarch64" ]; then
    case "$URL" in
        *x86_64*) URL="$(printf '%s' "$URL" | sed 's/x86_64/aarch64/')"; SHA="" ;;
        *aarch64*) ;;
        *) fail "pas de version ARM publiée pour $VERSION." ;;
    esac
elif [ "$ARCH" = "x86_64" ]; then
    case "$URL" in
        *aarch64*) fail "la version publiée ($VERSION) est pour ARM, pas pour ce PC x86_64." ;;
    esac
fi

say "Async Herald $VERSION ($ARCH)"
TMP="$(mktemp -d)"
trap 'rm -rf "$TMP"' EXIT INT TERM
download "$URL" "$TMP/app.AppImage" || fail "téléchargement impossible : $URL"

if [ -n "$SHA" ]; then
    GOT="$(sha256 "$TMP/app.AppImage")"
    [ "$GOT" = "$SHA" ] || fail "empreinte SHA-256 inattendue ($GOT au lieu de $SHA) : fichier non installé."
    say "Empreinte SHA-256 vérifiée."
else
    say "Attention : pas d'empreinte publiée pour la version ARM, fichier non vérifié."
fi

mkdir -p "$APP_DIR" "$BIN_DIR" "$(dirname "$DESKTOP")" "$(dirname "$ICON")"
mv "$TMP/app.AppImage" "$APP"
chmod 755 "$APP"
fetch "$SITE/angel.png" > "$ICON" 2>/dev/null || rm -f "$ICON"

# NixOS ne lance pas une AppImage telle quelle : passage par appimage-run.
if [ -e /etc/NIXOS ]; then
    cat > "$BIN" <<EOF
#!/bin/sh
if command -v appimage-run >/dev/null 2>&1; then exec appimage-run "$APP" "\$@"; fi
exec nix run nixpkgs#appimage-run -- "$APP" "\$@"
EOF
    chmod 755 "$BIN"
else
    ln -sf "$APP" "$BIN"
fi

cat > "$DESKTOP" <<EOF
[Desktop Entry]
Type=Application
Name=Async Herald
Comment=Analyse de code locale, sans IA
Exec=$BIN %U
Icon=async-herald
Terminal=false
Categories=Development;
StartupWMClass=herald-desktop
EOF
command -v update-desktop-database >/dev/null 2>&1 && update-desktop-database "$(dirname "$DESKTOP")" >/dev/null 2>&1 || true

say "Installé. Lancez Async Herald depuis le menu des applications, ou avec la commande : herald"
case ":$PATH:" in
    *":$BIN_DIR:"*) ;;
    *) say "Pour la commande herald, ajoutez $BIN_DIR à votre PATH (par exemple dans ~/.profile) : export PATH=\"$BIN_DIR:\$PATH\"" ;;
esac
