#!/bin/bash
#
# Nap installer — curl -fsSL https://trynap.app/install.sh | bash
#
# Downloads the current build, checks it against the SHA-256 published beside
# it, and puts Nap in Applications. Downloading with curl rather than a browser
# means macOS never quarantines it, so Nap opens without the Gatekeeper warning.
#
set -euo pipefail

BASE="${NAP_DOWNLOAD_BASE:-https://downloads.trynap.app}"
ZIP="Nap-latest.zip"
MIN_MACOS=13

bold=$'\033[1m'; dim=$'\033[2m'; red=$'\033[31m'; green=$'\033[32m'; off=$'\033[0m'
step () { printf '%s==>%s %s\n' "$bold" "$off" "$1"; }
fail () { printf '%s==>%s %s\n' "$red" "$off" "$1" >&2; exit 1; }

[ "$(uname -s)" = "Darwin" ] || fail "Nap is a macOS screensaver, and this isn't a Mac."

major=$(sw_vers -productVersion | cut -d. -f1)
[ "$major" -ge "$MIN_MACOS" ] || fail "Nap needs macOS $MIN_MACOS or later. This Mac runs $(sw_vers -productVersion)."

work=$(mktemp -d)
trap 'rm -rf "$work"' EXIT

step "Downloading Nap"
curl -fL --retry 3 --connect-timeout 20 --progress-bar -o "$work/$ZIP" "$BASE/$ZIP" \
  || fail "Couldn't download $BASE/$ZIP. Check your connection, or download Nap by hand from https://trynap.app/install."

step "Checking the download"
curl -fsSL --retry 3 -o "$work/$ZIP.sha256" "$BASE/$ZIP.sha256" \
  || fail "Couldn't fetch the checksum from $BASE/$ZIP.sha256."
want=$(awk '{print $1; exit}' "$work/$ZIP.sha256")
got=$(shasum -a 256 "$work/$ZIP" | awk '{print $1}')
[ -n "$want" ] || fail "The published checksum is empty. Nothing was installed."
if [ "$want" != "$got" ]; then
  fail "The download doesn't match its checksum, so it was thrown away.
    expected $want
    got      $got
  Try again, and if it keeps happening write to scanner@scannertechs.com."
fi
printf '    %ssha256 %s%s\n' "$dim" "$got" "$off"

step "Unpacking"
ditto -x -k "$work/$ZIP" "$work/unpacked" || fail "The download couldn't be unpacked."
app=$(find "$work/unpacked" -maxdepth 2 -name 'Nap.app' -print -quit)
[ -n "$app" ] || fail "That archive doesn't contain Nap.app."

# Signed by Scanner Techs, not notarised by Apple. A bad signature means a
# tampered or truncated bundle, so stop; an unsigned build is only a warning
# because the checksum above already matched what the site published.
if ! codesign --verify --deep --strict "$app" 2>/dev/null; then
  fail "The downloaded Nap isn't intact (its signature doesn't verify). Nothing was installed."
fi
# Read it all first: piping codesign into something that exits early (awk/head)
# kills it with SIGPIPE, and pipefail then takes the whole script down.
signature=$(codesign -dv --verbose=2 "$app" 2>&1 || true)
authority=$(printf '%s\n' "$signature" | sed -n 's/^Authority=//p' | sed -n 1p)
printf '    %ssigned by %s%s\n' "$dim" "${authority:-nobody}" "$off"

if [ -n "${NAP_INSTALL_DIR:-}" ]; then
  dest="$NAP_INSTALL_DIR"
  mkdir -p "$dest"
elif [ -w /Applications ]; then
  dest=/Applications
else
  dest="$HOME/Applications"
  mkdir -p "$dest"
  printf '    %s/Applications is not writable, so Nap goes in %s%s\n' "$dim" "$dest" "$off"
fi

# Replacing a running bundle leaves the open copy in a broken state, so stop it
# first. Nap is a settings window; nothing is lost by closing it.
if pgrep -x NapApp >/dev/null 2>&1; then
  step "Closing the copy of Nap that's open"
  pkill -x NapApp || true
  for _ in 1 2 3 4 5 6 7 8 9 10; do
    pgrep -x NapApp >/dev/null 2>&1 || break
    sleep 0.3
  done
fi

if [ -e "$dest/Nap.app" ]; then
  step "Replacing the Nap already in $dest"
  rm -rf "$dest/Nap.app"
else
  step "Installing to $dest"
fi
ditto "$app" "$dest/Nap.app" || fail "Couldn't write to $dest."

version=$(/usr/libexec/PlistBuddy -c 'Print :CFBundleShortVersionString' "$dest/Nap.app/Contents/Info.plist" 2>/dev/null || echo "")
printf '\n%s✓%s Nap %s installed in %s\n' "$green" "$off" "$version" "$dest"
echo "  Open it from Applications to start your free trial — it installs the screensavers for you."
echo "  Uninstall any time:  curl -fsSL https://trynap.app/uninstall.sh | bash"
