#!/bin/sh
# Kryptic daemon installer for Linux.
# Usage: curl -fsSL https://kryptic.dev/install.sh | sh
set -eu

BASE="${KRYPTIC_DOWNLOAD_BASE:-https://kryptic.dev}"

err() {
  printf 'kryptic: %s\n' "$*" >&2
}

info() {
  printf '%s\n' "$*"
}

need() {
  if ! command -v "$1" >/dev/null 2>&1; then
    err "missing required command: $1"
    exit 1
  fi
}

file_sha256() {
  if command -v sha256sum >/dev/null 2>&1; then
    sha256sum "$1" | awk '{print $1}'
  elif command -v shasum >/dev/null 2>&1; then
    shasum -a 256 "$1" | awk '{print $1}'
  elif command -v openssl >/dev/null 2>&1; then
    openssl dgst -sha256 "$1" | awk '{print $NF}'
  else
    err "need sha256sum, shasum, or openssl to verify the download"
    exit 1
  fi
}

checksum_for() {
  printf '%s\n' "$CHECKSUMS" | awk -v re="$1" '$2 ~ re { print $1; exit }'
}

download_verified() {
  remote="$1"
  check_re="$2"
  dest="$3"
  expected=$(checksum_for "$check_re")
  if [ -z "$expected" ]; then
    err "checksums.txt has no entry matching $check_re"
    exit 1
  fi
  info "Downloading $remote…"
  curl -fsSL "$BASE/dl/$remote" -o "$dest"
  actual=$(file_sha256 "$dest")
  if [ "$actual" != "$expected" ]; then
    err "checksum mismatch for $remote"
    err "  expected $expected"
    err "  got      $actual"
    exit 1
  fi
}

start_tray() {
  tray="$1"
  if [ ! -x "$tray" ]; then
    return 0
  fi
  if [ -z "${DISPLAY:-}${WAYLAND_DISPLAY:-}" ]; then
    info "Launch the desktop app with: $tray"
    return 0
  fi
  nohup "$tray" >/dev/null 2>&1 &
  info "Started the Kryptic tray. It will also start at login."
}

os=$(uname -s)
case "$os" in
  Linux) ;;
  Darwin)
    err "this script is for Linux. On macOS download the installer from $BASE/download"
    exit 1
    ;;
  *)
    err "unsupported OS '$os'. Download an installer from $BASE/download"
    exit 1
    ;;
esac

machine=$(uname -m)
case "$machine" in
  x86_64|amd64) ARCH=amd64 ;;
  aarch64|arm64) ARCH=arm64 ;;
  *)
    err "unsupported architecture '$machine'"
    exit 1
    ;;
esac

need curl

TMPDIR=$(mktemp -d)
trap 'rm -rf "$TMPDIR"' EXIT INT HUP

info "Fetching latest Kryptic release metadata…"
CHECKSUMS=$(curl -fsSL "$BASE/dl/checksums.txt")
if [ -z "$CHECKSUMS" ]; then
  err "could not download checksums from $BASE/dl/checksums.txt"
  exit 1
fi

if command -v systemctl >/dev/null 2>&1; then
  systemctl --user stop kryptic-daemon >/dev/null 2>&1 || true
fi
pkill -x kryptic-tray >/dev/null 2>&1 || true

download_verified "kryptic-linux-${ARCH}" "^kryptic_linux_${ARCH}$" "$TMPDIR/kryptic"
TRAY_RE="^kryptic-tray_linux_${ARCH}$"
if [ -n "$(checksum_for "$TRAY_RE")" ]; then
  download_verified "kryptic-tray-linux-${ARCH}" "$TRAY_RE" "$TMPDIR/kryptic-tray"
fi
info "Checksum verified."

BINDIR="$HOME/.local/bin"
APPDIR="$HOME/.local/share/applications"
AUTOSTART="$HOME/.config/autostart"
ICONDIR="$HOME/.local/share/icons/hicolor/256x256/apps"
SCALEDIR="$HOME/.local/share/icons/hicolor/scalable/apps"
PIXMAP="$HOME/.local/share/pixmaps"
mkdir -p "$BINDIR" "$APPDIR" "$AUTOSTART" "$ICONDIR" "$SCALEDIR" "$PIXMAP"
install -m 755 "$TMPDIR/kryptic" "$BINDIR/kryptic" 2>/dev/null || {
  cp "$TMPDIR/kryptic" "$BINDIR/kryptic"
  chmod 755 "$BINDIR/kryptic"
}
if [ -f "$TMPDIR/kryptic-tray" ]; then
  install -m 755 "$TMPDIR/kryptic-tray" "$BINDIR/kryptic-tray" 2>/dev/null || {
    cp "$TMPDIR/kryptic-tray" "$BINDIR/kryptic-tray"
    chmod 755 "$BINDIR/kryptic-tray"
  }
  ICON_FILE=kryptic
  if curl -fsSL "$BASE/kryptic.png" -o "$ICONDIR/kryptic.png"; then
    cp "$ICONDIR/kryptic.png" "$PIXMAP/kryptic.png"
    ICON_FILE="$ICONDIR/kryptic.png"
  fi
  if curl -fsSL "$BASE/kryptic.svg" -o "$SCALEDIR/kryptic.svg"; then
    cp "$SCALEDIR/kryptic.svg" "$PIXMAP/kryptic.svg"
    if [ "$ICON_FILE" = kryptic ]; then
      ICON_FILE="$SCALEDIR/kryptic.svg"
    fi
  fi
  cat > "$APPDIR/dev.kryptic.Kryptic.desktop" <<DESKTOP
[Desktop Entry]
Type=Application
Name=Kryptic
Comment=Local daemon and tray for Kryptic-managed secrets
Exec=$BINDIR/kryptic-tray
TryExec=$BINDIR/kryptic-tray
Icon=$ICON_FILE
Terminal=false
Categories=Utility;Security;
X-GNOME-UsesNotifications=true
X-GNOME-Autostart-enabled=true
DESKTOP
  cp "$APPDIR/dev.kryptic.Kryptic.desktop" "$AUTOSTART/dev.kryptic.Kryptic.desktop"
  if command -v update-desktop-database >/dev/null 2>&1; then
    update-desktop-database "$APPDIR" >/dev/null 2>&1 || true
  fi
  if command -v gtk-update-icon-cache >/dev/null 2>&1; then
    gtk-update-icon-cache -q "$HOME/.local/share/icons/hicolor" >/dev/null 2>&1 || true
  fi
fi

UNITDIR="$HOME/.config/systemd/user"
mkdir -p "$UNITDIR"
cat > "$UNITDIR/kryptic-daemon.service" <<'UNIT'
[Unit]
Description=Kryptic secrets daemon
Documentation=https://docs.kryptic.dev
After=network-online.target

[Service]
ExecStart=%h/.local/bin/kryptic start
Restart=on-failure
RestartSec=5
NoNewPrivileges=true
PrivateTmp=false
ProtectSystem=strict
ProtectHome=read-only
ReadWritePaths=%h/.config/kryptic
ReadWritePaths=/tmp

[Install]
WantedBy=default.target
UNIT

case ":$PATH:" in
  *":$BINDIR:"*) ;;
  *)
    info "Add $BINDIR to your PATH so the kryptic command is available in new terminals."
    ;;
esac

if command -v systemctl >/dev/null 2>&1 && [ "$(id -u)" -ne 0 ]; then
  systemctl --user daemon-reload >/dev/null 2>&1 || true
  systemctl --user enable --now kryptic-daemon >/dev/null 2>&1 || {
    info "Installed, but the user systemd service could not be started from this session."
    info "Start it with: systemctl --user enable --now kryptic-daemon"
  }
else
  info "Start the daemon with: kryptic start"
fi

if command -v kryptic-tray >/dev/null 2>&1; then
  start_tray "$(command -v kryptic-tray)"
elif [ -x "$HOME/.local/bin/kryptic-tray" ]; then
  start_tray "$HOME/.local/bin/kryptic-tray"
else
  info "Launch Kryptic from your app menu, or run: kryptic-tray"
fi

info
info "Done. Existing sign-in is kept. If this is a first install, run: kryptic login"
info "Tip: install secret-tool (libsecret) so the session token lives in your keyring."
