#!/usr/bin/env bash
# helvi.sh installer — one command to a running instance on any Linux box
# with Docker (offers to install Docker if missing).
#
#   curl -fsSL https://get.helvi.sh | sudo bash
#     (or)
#   sudo bash install.sh [--port 8080] [--image snaju/helvi:latest] \
#                        [--base-url https://helvi.example.com] [--yes]
#
# What it does, idempotently — rerun any time to upgrade:
#   1. ensures Docker is present (get.docker.com, after asking)
#   2. writes /etc/helvi/helvi.env  (generated vault passphrase, your answers)
#   3. pulls the image and (re)creates the `helvi` container
#      - data volume:  /var/lib/helvi  (SQLite DB, key-vault seal, recordings)
#      - restart policy: unless-stopped
#   4. prints the URL; the first visit runs the setup wizard (org + admin)
#
# State survives upgrades: only the container is recreated, never the data
# dir or the env file. To uninstall: docker rm -f helvi && rm -rf
# /etc/helvi /var/lib/helvi (the data dir holds every secret — think first).
set -euo pipefail

IMAGE="snaju/helvi:latest"
PORT="8080"
BASE_URL=""
ASSUME_YES=0
DATA_DIR="/var/lib/helvi"
ENV_FILE="/etc/helvi/helvi.env"

while [ $# -gt 0 ]; do
  case "$1" in
    --image)    IMAGE="$2"; shift 2 ;;
    --port)     PORT="$2"; shift 2 ;;
    --base-url) BASE_URL="$2"; shift 2 ;;
    --yes|-y)   ASSUME_YES=1; shift ;;
    *) echo "unknown flag: $1" >&2; exit 2 ;;
  esac
done

say()  { printf '\033[1;36m==>\033[0m %s\n' "$*"; }
fail() { printf '\033[1;31merror:\033[0m %s\n' "$*" >&2; exit 1; }

confirm() { # confirm "question" — honors --yes, defaults to yes on Enter
  [ "$ASSUME_YES" = 1 ] && return 0
  # When piped through `curl | bash`, stdin is the script — ask via /dev/tty.
  local reply
  if [ -t 0 ]; then read -r -p "$1 [Y/n] " reply; else read -r -p "$1 [Y/n] " reply < /dev/tty; fi
  case "$reply" in n|N|no|NO) return 1 ;; *) return 0 ;; esac
}

[ "$(id -u)" = 0 ] || fail "run as root:  curl -fsSL https://get.helvi.sh | sudo bash"
command -v curl >/dev/null || fail "curl is required"

# --- 1. Docker ---------------------------------------------------------------
if ! command -v docker >/dev/null 2>&1; then
  say "Docker is not installed."
  confirm "Install Docker now via get.docker.com?" || fail "Docker is required — install it and rerun."
  curl -fsSL https://get.docker.com | sh
fi
docker info >/dev/null 2>&1 || fail "Docker daemon is not running (systemctl start docker)"

# --- 2. Config ---------------------------------------------------------------
mkdir -p "$(dirname "$ENV_FILE")" "$DATA_DIR"

if [ ! -f "$ENV_FILE" ]; then
  say "First install — writing $ENV_FILE"

  # The vault passphrase seals the SSH key store (age KEK). Losing it means
  # re-importing every key, so it lives in the env file, root-only.
  PASSPHRASE="$(head -c 32 /dev/urandom | od -An -tx1 | tr -d ' \n')"

  if [ -z "$BASE_URL" ]; then
    GUESS_IP="$(hostname -I 2>/dev/null | awk '{print $1}')"
    BASE_URL="http://${GUESS_IP:-localhost}:${PORT}"
    say "No --base-url given; assuming ${BASE_URL}"
    say "(set the real public URL later in $ENV_FILE — needed for SSO redirects)"
  fi

  # secure_cookies must match the scheme: on plain HTTP a Secure cookie is
  # silently dropped by the browser and login can never complete.
  case "$BASE_URL" in
    https://*) SECURE_COOKIES=true ;;
    *)         SECURE_COOKIES=false
               say "WARNING: ${BASE_URL} is plain HTTP — fine on a trusted LAN,"
               say "         but put Caddy/Traefik/nginx with TLS in front for anything else." ;;
  esac

  cat > "$ENV_FILE" <<EOF
# helvi.sh runtime config (docker --env-file). Full reference:
# https://github.com/snaju/helvi — deploy/helvi.env.example
HELVI_SERVER__BASE_URL=${BASE_URL}
HELVI_SERVER__SECURE_COOKIES=${SECURE_COOKIES}
HELVI_VAULT__PASSPHRASE=${PASSPHRASE}
EOF
  chmod 600 "$ENV_FILE"
else
  say "Keeping existing $ENV_FILE"
fi

# --- 3. Pull + (re)create container -------------------------------------------
say "Pulling ${IMAGE}"
docker pull "$IMAGE"

if docker inspect helvi >/dev/null 2>&1; then
  say "Recreating container (upgrade)"
  docker rm -f helvi >/dev/null
fi

docker run -d \
  --name helvi \
  --restart unless-stopped \
  -p "${PORT}:8080" \
  --env-file "$ENV_FILE" \
  -v "${DATA_DIR}:/var/lib/helvi" \
  "$IMAGE" >/dev/null

# --- 4. Wait + report -----------------------------------------------------------
say "Waiting for helvi to come up…"
for _ in $(seq 1 30); do
  if curl -fsS "http://127.0.0.1:${PORT}/healthz" >/dev/null 2>&1; then
    BASE_SHOWN="$(grep -oP '(?<=^HELVI_SERVER__BASE_URL=).*' "$ENV_FILE" || true)"
    echo
    say "helvi.sh is running."
    echo "    URL:        ${BASE_SHOWN:-http://localhost:$PORT}"
    echo "    First visit: setup wizard (name your org, create the admin account)"
    echo "    Data:       ${DATA_DIR}    Config: ${ENV_FILE}"
    echo "    Upgrade:    rerun this installer    Logs: docker logs -f helvi"
    exit 0
  fi
  sleep 1
done
fail "container did not become healthy — check: docker logs helvi"
