#!/bin/sh
# Install or update PG Orbit on Linux: https://pgorbit.com/linux
#
#   curl -fsSL https://pgorbit.com/install.sh | sh
#   curl -fsSL https://pgorbit.com/install.sh | sh -s -- --uninstall
#
# Puts the AppImage in ~/.local/share/pg-orbit, a `pg-orbit` command in
# ~/.local/bin, and PG Orbit in your desktop's app launcher. Run it again to
# update. Nothing is installed system-wide and no root access is needed.
set -eu

SITE="${PGORBIT_SITE:-https://pgorbit.com}"
APP_ID="com.acrogenesis.pgOrbit"
DATA_HOME="${XDG_DATA_HOME:-$HOME/.local/share}"
APP_DIR="$DATA_HOME/pg-orbit"
APPIMAGE="$APP_DIR/PG_Orbit.AppImage"
BIN="$HOME/.local/bin/pg-orbit"
DESKTOP="$DATA_HOME/applications/$APP_ID.desktop"
ICON_SIZES="128 256 512"

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

uninstall() {
  rm -f "$APPIMAGE" "$BIN"
  rmdir "$APP_DIR" 2>/dev/null || true
  if [ -f "$DESKTOP" ] && grep -q '^X-PGOrbit-Managed=true' "$DESKTOP"; then
    rm -f "$DESKTOP"
    for size in $ICON_SIZES; do
      rm -f "$DATA_HOME/icons/hicolor/${size}x$size/apps/$APP_ID.png"
    done
  fi
  say "PG Orbit removed. Your connections and settings are kept in ~/.local/share/$APP_ID."
}

if [ "${1:-}" = "--uninstall" ]; then
  uninstall
  exit 0
fi

[ "$(uname -s)" = Linux ] || fail "this installer is for Linux."
[ "$(uname -m)" = x86_64 ] || fail "PG Orbit for Linux is x86_64 only for now."
command -v curl >/dev/null || fail "curl is required."
command -v sha256sum >/dev/null || fail "sha256sum is required."

version=$(curl -fsSL "$SITE/linux/latest.json" | sed -n 's/.*"version" *: *"\([^"]*\)".*/\1/p')
[ -n "$version" ] || fail "couldn't read the latest version from $SITE."

name="PG_Orbit-$version-x86_64.AppImage"
url="https://github.com/acrogenesis/pg-orbit-releases/releases/download/v$version/$name"
tmp=$(mktemp -d)
trap 'rm -rf "$tmp"' EXIT

say "Downloading PG Orbit $version..."
curl -fL --progress-bar -o "$tmp/$name" "$url"
curl -fsSL -o "$tmp/$name.sha256" "$url.sha256"
(cd "$tmp" && sha256sum -c --quiet "$name.sha256") || fail "the download's checksum doesn't match."

mkdir -p "$APP_DIR" "$(dirname "$BIN")" "$(dirname "$DESKTOP")"
chmod +x "$tmp/$name"
mv -f "$tmp/$name" "$APPIMAGE"
ln -sf "$APPIMAGE" "$BIN"

# Icons come from inside the AppImage; extracting doesn't need FUSE.
(cd "$tmp" && "$APPIMAGE" --appimage-extract 'usr/share/icons/*' >/dev/null 2>&1) || true
for size in $ICON_SIZES; do
  icon="$tmp/squashfs-root/usr/share/icons/hicolor/${size}x$size/apps/$APP_ID.png"
  if [ -f "$icon" ]; then
    mkdir -p "$DATA_HOME/icons/hicolor/${size}x$size/apps"
    cp -f "$icon" "$DATA_HOME/icons/hicolor/${size}x$size/apps/"
  fi
done

# The same entry PG Orbit writes for itself, so the two never disagree.
case "$APPIMAGE" in
  *[!A-Za-z0-9/._+-]*) exec_line="\"$APPIMAGE\"" ;;
  *) exec_line="$APPIMAGE" ;;
esac
cat >"$DESKTOP" <<EOF
[Desktop Entry]
Type=Application
Name=PG Orbit
Comment=PostgreSQL client
Exec=$exec_line
TryExec=$APPIMAGE
Icon=$APP_ID
Categories=Development;Database;
Terminal=false
StartupWMClass=$APP_ID
X-PGOrbit-Managed=true
EOF
command -v update-desktop-database >/dev/null && update-desktop-database -q "$DATA_HOME/applications" 2>/dev/null || true

say "PG Orbit $version is installed. Find it in your app launcher, or run: pg-orbit"
case ":$PATH:" in
  *":$HOME/.local/bin:"*) ;;
  *) say "Note: ~/.local/bin isn't on your PATH, so the pg-orbit command needs its full path." ;;
esac
if ! command -v fusermount3 >/dev/null && ! command -v fusermount >/dev/null; then
  say "Note: AppImages need FUSE. If PG Orbit doesn't start, install your distribution's fuse3 package."
fi
