#!/bin/sh
# Pasiv for Linux — one-line install.
#
#   curl -fsSL https://pasiv.network/linux.sh | sh
#
# Installs the Pasiv desktop app as a native package — a .deb on Debian/Ubuntu
# (apt), an .rpm on Fedora/openSUSE (dnf/zypper) — and from then on it updates
# itself (the package ships a root-side updater + daily timer, and the app's
# Update button hands off to it). Nothing mines until you press the button in
# the app.
#
# Trust: the package is downloaded from Pasiv's public releases and must carry
# a valid minisign signature from the SAME key every Pasiv update is signed
# with. That key is pinned HERE, in a script served from pasiv.network — an
# origin independent of the release host — so replacing a package (and its
# checksum) on the release host still cannot get past this script.
set -eu

RELEASES="https://pasiv.network/update"
MINISIGN_PUB="RWQJhawYO7igroqjh+CUPCstCmt4Ka2DAmznjX2e1gsScv3k5u7jYWR3"
# Our mirror first (pasiv.network: no git host on the install path), the
# upstream release second. Same file either way: the SHA-256 below is pinned.
MINISIGN_TGZ="https://pasiv.network/releases/tools/minisign-0.12-linux.tar.gz"
MINISIGN_TGZ_ALT="https://github.com/jedisct1/minisign/releases/download/0.12/minisign-0.12-linux.tar.gz"
MINISIGN_TGZ_SHA256="9a599b48ba6eb7b1e80f12f36b94ceca7c00b7a5173c95c3efc88d9822957e73"

case "$(uname -s)-$(uname -m)" in
  Linux-x86_64) ;;
  *) echo "Pasiv for Linux ships for x86-64 only (got $(uname -s)-$(uname -m))."; exit 1 ;;
esac

SUDO=""
[ "$(id -u)" -eq 0 ] || SUDO="sudo"

if command -v apt-get >/dev/null 2>&1; then
  KIND=deb
elif command -v dnf >/dev/null 2>&1 || command -v zypper >/dev/null 2>&1; then
  KIND=rpm
else
  echo "This installer supports apt (Debian/Ubuntu) and dnf/zypper (Fedora/openSUSE)."
  echo "Download a package by hand from https://pasiv.network/install"
  exit 1
fi

echo "→ finding the latest Pasiv"
VERSION=$(curl -fsSL "$RELEASES/latest.json" \
  | sed -n 's/.*"version"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' | head -1)
[ -n "$VERSION" ] || { echo "Couldn't read the latest version — check your connection."; exit 1; }
# The version becomes part of a file path below, and latest.json lives on the
# release host this script deliberately does not trust. Accept only a plain
# dotted version, so a tampered manifest cannot steer where the download lands.
case "$VERSION" in
  *[!0-9.]*|.*|*.) echo "Unexpected version '$VERSION' in latest.json — refusing to install." >&2; exit 1 ;;
esac
if [ "$KIND" = deb ]; then PKG="Pasiv_${VERSION}_amd64.deb"; else PKG="Pasiv-${VERSION}-1.x86_64.rpm"; fi
echo "  Pasiv $VERSION ($PKG)"

TMP="$(mktemp -d)"
trap 'rm -rf "$TMP"' EXIT
echo "→ downloading"
curl -fsSL "$RELEASES/$PKG" -o "$TMP/$PKG"

sha256_of() {
  if command -v sha256sum >/dev/null 2>&1; then sha256sum "$1" | awk '{print $1}'
  else shasum -a 256 "$1" | awk '{print $1}'; fi
}

# minisign: from the distro if packaged, else the author's build pinned by hash.
MS="$(command -v minisign 2>/dev/null || true)"
if [ -z "$MS" ]; then
  echo "→ installing minisign (needed to verify the download)"
  if [ "$KIND" = deb ]; then
    $SUDO env DEBIAN_FRONTEND=noninteractive apt-get install -y -qq minisign >/dev/null 2>&1 || true
  elif command -v dnf >/dev/null 2>&1; then
    $SUDO dnf install -y -q minisign >/dev/null 2>&1 || true
  fi
  MS="$(command -v minisign 2>/dev/null || true)"
fi
if [ -z "$MS" ]; then
  if { curl -fsSL "$MINISIGN_TGZ" -o "$TMP/ms.tgz" || curl -fsSL "$MINISIGN_TGZ_ALT" -o "$TMP/ms.tgz"; } \
     && [ "$(sha256_of "$TMP/ms.tgz")" = "$MINISIGN_TGZ_SHA256" ] \
     && tar xzf "$TMP/ms.tgz" -C "$TMP" 2>/dev/null \
     && [ -x "$TMP/minisign-linux/x86_64/minisign" ]; then
    MS="$TMP/minisign-linux/x86_64/minisign"
  fi
fi
[ -n "$MS" ] || { echo "minisign is required to verify Pasiv and couldn't be installed — refusing to install." >&2; exit 1; }

echo "→ verifying signature"
curl -fsSL "$RELEASES/$PKG.minisig" -o "$TMP/$PKG.minisig" \
  || { echo "No signature published for $PKG — refusing to install." >&2; exit 1; }
"$MS" -Vm "$TMP/$PKG" -x "$TMP/$PKG.minisig" -P "$MINISIGN_PUB" >/dev/null \
  || { echo "SIGNATURE VERIFICATION FAILED — refusing to install." >&2; exit 1; }
echo "  ✓ signed by Pasiv"

echo "→ installing"
# The package manager, not bare dpkg/rpm, so dependencies are pulled in.
chmod 644 "$TMP/$PKG"
if [ "$KIND" = deb ]; then
  $SUDO env DEBIAN_FRONTEND=noninteractive apt-get install -y -q "$TMP/$PKG"
elif command -v dnf >/dev/null 2>&1; then
  $SUDO dnf install -y -q "$TMP/$PKG"
else
  $SUDO zypper --non-interactive install --allow-unsigned-rpm "$TMP/$PKG"
fi

cat <<EOF

  Pasiv $VERSION is installed, and it will keep itself up to date.

  Open it from your apps menu (or run: pasiv), then press the pearl to start.
  Nothing mines until you do.

EOF

# Start it now for a desktop user running this in their own session.
if [ "$(id -u)" -ne 0 ] && { [ -n "${WAYLAND_DISPLAY:-}" ] || [ -n "${DISPLAY:-}" ]; }; then
  (setsid pasiv >/dev/null 2>&1 &) || true
fi
