#!/usr/bin/env bash
# AltoSignal -- remove a per-user tarball install.
#
# ⚠️ SETTINGS ARE KEPT BY DEFAULT. The program files and a practice's channel
# configuration live in two directories whose names differ by one word:
#     program   ~/.local/share/altosignal
#     settings  ~/.local/share/com.altosignal.altosignal
# Removing the second one loses the configuration, so it happens ONLY with an
# explicit --purge and only after this script has confirmed what it is deleting.
#
# ⚠️ EVERY REMOVAL BELOW IS A FIXED PATH THAT IS VERIFIED FIRST. Nothing here
# expands a glob or a variable into rm -rf without checking the target is the
# thing it claims to be -- a wrong match would take a user's home directory with it.

set -euo pipefail

APP_ID="com.altosignal.altosignal"
BIN_NAME="altosignal"

DATA_HOME="${XDG_DATA_HOME:-$HOME/.local/share}"
APP_DIR="$DATA_HOME/altosignal"
SETTINGS_DIR="$DATA_HOME/$APP_ID"
DESKTOP_DIR="$DATA_HOME/applications"
ICON_ROOT="$DATA_HOME/icons/hicolor"
DESKTOP_FILE="$DESKTOP_DIR/$APP_ID.desktop"

PURGE=0
[ "${1:-}" = "--purge" ] && PURGE=1
if [ -n "${1:-}" ] && [ "${1:-}" != "--purge" ]; then
  printf 'usage: %s [--purge]\n  --purge  also delete settings in %s\n' "$0" "$SETTINGS_DIR" >&2
  exit 2
fi

die()  { printf '\n[FAIL] %s\n' "$*" >&2; exit 1; }
step() { printf '\n== %s\n' "$*"; }
ok()   { printf '   ok  %s\n' "$*"; }
skip() { printf '   --  %s\n' "$*"; }

step "1. program files"
if [ -d "$APP_DIR" ]; then
  # Three independent checks before a recursive delete: the path is the literal we
  # constructed, its basename is what we expect, and it really contains our binary.
  [ "$APP_DIR" = "$DATA_HOME/altosignal" ] || die "refusing: APP_DIR was reassigned"
  [ "$(basename "$APP_DIR")" = "altosignal" ] || die "refusing: unexpected basename"
  [ -f "$APP_DIR/$BIN_NAME" ] || die "refusing to delete $APP_DIR -- it does not contain
       $BIN_NAME, so it is not an AltoSignal install and this script did not create it."
  rm -rf "$APP_DIR"
  ok "removed $APP_DIR"
else
  skip "no program files at $APP_DIR"
fi

step "2. launcher"
if [ -f "$DESKTOP_FILE" ]; then
  rm -f "$DESKTOP_FILE"
  ok "removed $DESKTOP_FILE"
else
  skip "no launcher at $DESKTOP_FILE"
fi

step "3. icons"
n=0
# Enumerate the exact per-size paths rather than globbing under the icon root.
for d in "$ICON_ROOT"/*/apps; do
  [ -d "$d" ] || continue
  if [ -f "$d/$APP_ID.png" ]; then
    rm -f "$d/$APP_ID.png"
    n=$((n + 1))
  fi
done
[ "$n" -gt 0 ] && ok "removed $n icon files" || skip "no icons found"

step "4. settings"
if [ "$PURGE" -eq 1 ]; then
  if [ -d "$SETTINGS_DIR" ]; then
    [ "$SETTINGS_DIR" = "$DATA_HOME/$APP_ID" ] || die "refusing: SETTINGS_DIR was reassigned"
    printf '   about to delete settings: %s\n' "$SETTINGS_DIR"
    ls -A "$SETTINGS_DIR" | sed 's/^/       /'
    rm -rf "$SETTINGS_DIR"
    ok "purged settings"
  else
    skip "no settings at $SETTINGS_DIR"
  fi
else
  if [ -d "$SETTINGS_DIR" ]; then
    ok "settings KEPT at $SETTINGS_DIR (re-run with --purge to delete them)"
  else
    skip "no settings directory"
  fi
fi

step "5. refresh caches"
command -v update-desktop-database >/dev/null 2>&1 \
  && update-desktop-database "$DESKTOP_DIR" 2>/dev/null && ok "desktop database updated" \
  || skip "desktop database refresh skipped"
command -v gtk-update-icon-cache >/dev/null 2>&1 \
  && gtk-update-icon-cache -f -t "$ICON_ROOT" 2>/dev/null && ok "icon cache updated" \
  || skip "icon cache refresh skipped"

printf '\nDone.\n'
