#!/usr/bin/env bash
# Photarium installer — Debian, Ubuntu and Fedora (amd64, arm64).
#
#   curl -fsSL https://dl.photarium.waxquixotic.com/install.sh | sudo bash
#
# Asks for anything it needs. For unattended installs (automation, AI
# agents) pass every setting as a PHOTARIUM_* variable and set
# PHOTARIUM_NONINTERACTIVE=1; the full list is at
# https://photarium.waxquixotic.com/install.html (and /install.md).
#
# Re-running it on a machine that already has Photarium upgrades the
# binaries in place and keeps the existing configuration.
#
# Photarium is free software under the GNU AGPL v3.0.
set -euo pipefail

DL_BASE="${PHOTARIUM_DL_BASE:-https://dl.photarium.waxquixotic.com}"
PREFIX=/opt/photarium
CONF_DIR=/etc/photarium
CONF="$CONF_DIR/photarium.env"
DATA=/var/lib/photarium
UNIT_DIR=/etc/systemd/system
SVC_USER=photarium
LOCAL_HTTP=127.0.0.1:8080

# --- output -----------------------------------------------------------------

if [[ -t 1 ]]; then
  B=$'\033[1m' G=$'\033[32m' Y=$'\033[33m' R=$'\033[31m' N=$'\033[0m'
else
  B='' G='' Y='' R='' N=''
fi
say()  { printf '%s==>%s %s\n' "$G$B" "$N" "$*"; }
warn() { printf '%sWARNING:%s %s\n' "$Y$B" "$N" "$*" >&2; }
die()  { printf '%sERROR:%s %s\n' "$R$B" "$N" "$*" >&2; exit 1; }

# --- prompting ----------------------------------------------------------------
# Piped from curl, stdin is the script itself, so questions go to /dev/tty.

INTERACTIVE=0
if [[ "${PHOTARIUM_NONINTERACTIVE:-0}" != "1" ]] && { : </dev/tty; } 2>/dev/null; then
  INTERACTIVE=1
fi

# ask VAR "question" [default] [secret]
# Keeps VAR if it is already set (from the environment); otherwise asks, or
# falls back to the default, or fails when there is neither.
ask() {
  local var=$1 question=$2 default=${3-} secret=${4-} answer
  if [[ -n "${!var:-}" ]]; then return; fi
  if [[ $INTERACTIVE == 1 ]]; then
    while :; do
      if [[ -n $default ]]; then
        printf '%s%s%s [%s]: ' "$B" "$question" "$N" "$default" >/dev/tty
      else
        printf '%s%s%s: ' "$B" "$question" "$N" >/dev/tty
      fi
      if [[ -n $secret ]]; then
        IFS= read -rs answer </dev/tty
        printf '\n' >/dev/tty
      else
        IFS= read -r answer </dev/tty
      fi
      answer=${answer:-$default}
      [[ -n $answer || $default == "-" ]] && break
      printf '  (required)\n' >/dev/tty
    done
    [[ $answer == "-" ]] && answer=""
    printf -v "$var" '%s' "$answer"
  elif [[ -n $default ]]; then
    [[ $default == "-" ]] && default=""
    printf -v "$var" '%s' "$default"
  else
    die "$var is required (no terminal to ask on). See https://photarium.waxquixotic.com/install.html"
  fi
}

yes_no() { [[ ${1,,} =~ ^(y|yes|true|1)$ ]]; }

# --- system checks ------------------------------------------------------------

[[ $EUID -eq 0 ]] || die "run as root: curl -fsSL $DL_BASE/install.sh | sudo bash"
[[ -d /run/systemd/system ]] || die "systemd is required (this system isn't running it)"

case "$(uname -m)" in
  x86_64 | amd64) ARCH=amd64 ;;
  aarch64 | arm64) ARCH=arm64 ;;
  *) die "unsupported CPU architecture $(uname -m); Photarium provides amd64 and arm64" ;;
esac

OS_ID=unknown OS_LIKE=""
if [[ -r /etc/os-release ]]; then
  # shellcheck disable=SC1091
  . /etc/os-release
  OS_ID=${ID:-unknown} OS_LIKE=${ID_LIKE:-}
fi
if command -v apt-get >/dev/null; then
  PKG=apt
elif command -v dnf >/dev/null; then
  PKG=dnf
else
  PKG=none
fi
case "$OS_ID $OS_LIKE" in
  *debian* | *ubuntu* | *fedora* | *rhel*) ;;
  *) warn "untested distribution ($OS_ID); continuing — Debian, Ubuntu and Fedora are supported" ;;
esac

install_packages() {
  case $PKG in
    apt)
      DEBIAN_FRONTEND=noninteractive apt-get update -qq
      DEBIAN_FRONTEND=noninteractive apt-get install -y -qq "$@" >/dev/null
      ;;
    dnf) dnf install -y -q "$@" >/dev/null ;;
    *) die "please install: $*" ;;
  esac
}

missing=()
for tool in curl tar sha256sum base64; do
  command -v "$tool" >/dev/null || missing+=("$tool")
done
[[ -f /etc/ssl/certs/ca-certificates.crt || -f /etc/pki/tls/certs/ca-bundle.crt ]] || missing+=(ca-certificates)
if ((${#missing[@]})); then
  say "Installing prerequisites: ${missing[*]}"
  pkgs=()
  for m in "${missing[@]}"; do
    case $m in sha256sum | base64) pkgs+=(coreutils) ;; *) pkgs+=("$m") ;; esac
  done
  install_packages "${pkgs[@]}"
fi

UPGRADE=0
[[ -f $CONF ]] && UPGRADE=1

# --- configuration (fresh installs only) ----------------------------------------

gen_secret() { head -c 48 /dev/urandom | base64 | tr -d '\n'; }
gen_password() { head -c 64 /dev/urandom | base64 | tr -dc 'A-Za-z0-9' | cut -c1-20; }

configure() {
  if [[ $INTERACTIVE == 1 ]]; then
    cat >/dev/tty <<EOF

${B}Photarium setup${N} — press Enter to accept a [default].
Guide: https://photarium.waxquixotic.com/install.html

EOF
  fi
  ask PHOTARIUM_DOMAIN "Domain name for your gallery (e.g. photos.example.com)"
  PHOTARIUM_DOMAIN=${PHOTARIUM_DOMAIN#http://}
  PHOTARIUM_DOMAIN=${PHOTARIUM_DOMAIN#https://}
  PHOTARIUM_DOMAIN=${PHOTARIUM_DOMAIN%%/*}
  [[ $PHOTARIUM_DOMAIN =~ ^[A-Za-z0-9]([A-Za-z0-9.-]*[A-Za-z0-9])?$ && $PHOTARIUM_DOMAIN == *.* ]] ||
    die "'$PHOTARIUM_DOMAIN' is not a domain name"

  if [[ $INTERACTIVE == 1 && -z ${PHOTARIUM_TLS:-} ]]; then
    cat >/dev/tty <<EOF

How will HTTPS reach this server?
  auto    Photarium gets its own Let's Encrypt certificate. Ports 80 and 443
          must reach this server directly (DNS record NOT proxied by Cloudflare).
  tunnel  Cloudflare Tunnel: no open ports at all, Cloudflare in front.
          Recommended if you use Cloudflare. Needs a tunnel token.
  proxy   Plain HTTP on $LOCAL_HTTP behind your own reverse proxy.
EOF
  fi
  ask PHOTARIUM_TLS "HTTPS mode (auto/tunnel/proxy)" auto
  case $PHOTARIUM_TLS in auto | tunnel | proxy) ;; *) die "PHOTARIUM_TLS must be auto, tunnel or proxy" ;; esac

  if [[ $PHOTARIUM_TLS == tunnel ]]; then
    ask PHOTARIUM_TUNNEL_TOKEN "Cloudflare Tunnel token (dashboard > Networking > Tunnels > Create a tunnel)" "" secret
    PHOTARIUM_BEHIND_CLOUDFLARE=yes
  else
    ask PHOTARIUM_BEHIND_CLOUDFLARE "Is the domain proxied through Cloudflare (orange cloud)? (yes/no)" no
  fi
  if [[ $PHOTARIUM_TLS == auto ]]; then
    ask PHOTARIUM_ACME_EMAIL "Email for Let's Encrypt notices (optional)" "-"
    if yes_no "$PHOTARIUM_BEHIND_CLOUDFLARE"; then
      warn "auto HTTPS can't get a certificate through Cloudflare's proxy. Use PHOTARIUM_TLS=tunnel, or set the DNS record to 'DNS only'."
    fi
  fi

  ask PHOTARIUM_AUTO_UPDATE "Install updates automatically? (idle = when the server is quiet, scheduled = at 03:00, off = only when you click Update now)" idle
  case $PHOTARIUM_AUTO_UPDATE in idle | scheduled | off) ;; *) die "PHOTARIUM_AUTO_UPDATE must be idle, scheduled or off" ;; esac

  ask PHOTARIUM_ADMIN_USER "Admin username" admin
  GENERATED_PASSWORD=0
  if [[ -z ${PHOTARIUM_ADMIN_PASSWORD:-} ]]; then
    if [[ $INTERACTIVE == 1 ]]; then
      ask PHOTARIUM_ADMIN_PASSWORD "Admin password (Enter to generate one)" "-" secret
    fi
    if [[ -z ${PHOTARIUM_ADMIN_PASSWORD:-} ]]; then
      PHOTARIUM_ADMIN_PASSWORD=$(gen_password)
      GENERATED_PASSWORD=1
    fi
  fi
  ((${#PHOTARIUM_ADMIN_PASSWORD} >= 8)) || die "the admin password must be at least 8 characters"

  if [[ $INTERACTIVE == 1 && -z ${PHOTARIUM_STORAGE:-} ]]; then
    cat >/dev/tty <<EOF

Storage: two buckets — one PUBLIC (photos anyone may view) and one PRIVATE
(private photos and database backups). Setup guides for each provider:
https://photarium.waxquixotic.com/install.html#storage
EOF
  fi
  ask PHOTARIUM_STORAGE "Storage provider (b2/wasabi/r2/s3)" b2
  local endpoint region="" public_url_default=""
  case $PHOTARIUM_STORAGE in
    b2)
      ask PHOTARIUM_S3_REGION "B2 region, from the bucket's endpoint s3.<region>.backblazeb2.com (e.g. us-west-004)"
      endpoint="https://s3.$PHOTARIUM_S3_REGION.backblazeb2.com"
      region=$PHOTARIUM_S3_REGION
      ;;
    wasabi)
      ask PHOTARIUM_S3_REGION "Wasabi region (e.g. us-east-1)" us-east-1
      endpoint="https://s3.$PHOTARIUM_S3_REGION.wasabisys.com"
      region=$PHOTARIUM_S3_REGION
      ;;
    r2)
      ask PHOTARIUM_R2_ACCOUNT_ID "Cloudflare account ID (R2 overview page)"
      endpoint="https://$PHOTARIUM_R2_ACCOUNT_ID.r2.cloudflarestorage.com"
      region=auto
      ;;
    s3)
      ask PHOTARIUM_S3_ENDPOINT "S3 endpoint URL (e.g. https://s3.example.com)"
      ask PHOTARIUM_S3_REGION "Region (optional)" "-"
      region=$PHOTARIUM_S3_REGION
      ;;
    *) die "PHOTARIUM_STORAGE must be b2, wasabi, r2 or s3" ;;
  esac
  endpoint=${PHOTARIUM_S3_ENDPOINT:-$endpoint}

  ask PHOTARIUM_PUBLIC_BUCKET "Public bucket name"
  ask PHOTARIUM_PRIVATE_BUCKET "Private bucket name"
  [[ $PHOTARIUM_PUBLIC_BUCKET != "$PHOTARIUM_PRIVATE_BUCKET" ]] || die "the public and private buckets must be different buckets"
  ask PHOTARIUM_S3_KEY_ID "Access key ID"
  ask PHOTARIUM_S3_SECRET "Secret access key" "" secret
  if [[ -z ${PHOTARIUM_PRIVATE_S3_KEY_ID:-} && $INTERACTIVE == 1 ]]; then
    local separate
    ask separate "Separate key for the private bucket? (yes/no)" no
    if yes_no "$separate"; then
      ask PHOTARIUM_PRIVATE_S3_KEY_ID "Private bucket access key ID"
      ask PHOTARIUM_PRIVATE_S3_SECRET "Private bucket secret access key" "" secret
    fi
  fi

  case $PHOTARIUM_STORAGE in
    b2) public_url_default="https://$PHOTARIUM_PUBLIC_BUCKET.s3.$PHOTARIUM_S3_REGION.backblazeb2.com" ;;
    wasabi) public_url_default="https://s3.$PHOTARIUM_S3_REGION.wasabisys.com/$PHOTARIUM_PUBLIC_BUCKET" ;;
  esac
  ask PHOTARIUM_PUBLIC_URL "Public URL of the public bucket (no trailing slash)" "$public_url_default"
  PHOTARIUM_PUBLIC_URL=${PHOTARIUM_PUBLIC_URL%/}

  ask PHOTARIUM_CF_API_TOKEN "Cloudflare API token for cache purges (optional; only if Cloudflare caches your images)" "-" secret
  if [[ -n $PHOTARIUM_CF_API_TOKEN ]]; then
    ask PHOTARIUM_CF_ZONE_ID "Cloudflare zone ID of the image domain"
  fi

  local tls_domain="" http_addr=$LOCAL_HTTP client_ip=""
  [[ $PHOTARIUM_TLS == auto ]] && tls_domain=$PHOTARIUM_DOMAIN http_addr=":80"
  yes_no "$PHOTARIUM_BEHIND_CLOUDFLARE" && client_ip=CF-Connecting-IP

  local v
  for v in PHOTARIUM_S3_SECRET PHOTARIUM_PRIVATE_S3_SECRET PHOTARIUM_CF_API_TOKEN PHOTARIUM_PUBLIC_URL; do
    [[ ${!v:-} != *$'\n'* ]] || die "$v contains a line break"
  done

  say "Writing $CONF"
  install -d -m 0750 -o root -g "$SVC_USER" "$CONF_DIR"
  local tmp
  tmp=$(mktemp "$CONF_DIR/.photarium.env.XXXXXX")
  cat >"$tmp" <<EOF
# Photarium configuration — written by install.sh on $(date -u +%Y-%m-%d).
# Every setting is explained in /opt/photarium/photarium.env.example.
# After editing: sudo systemctl restart photarium

WEB_ORIGIN=https://$PHOTARIUM_DOMAIN
TLS_DOMAIN=$tls_domain
TLS_EMAIL=${PHOTARIUM_ACME_EMAIL:-}
HTTP_ADDR=$http_addr
DB_PATH=$DATA/photos.db
SESSION_SECRET=$(gen_secret)
SERVE_UI=true
SITE_NAME=Photarium
OWNER_NAME=
CLIENT_IP_HEADER=$client_ip
BODY_LIMIT_MB=64

# Updates: photosd checks for new releases and installs them itself through
# the photarium-update service (Settings > Software updates changes how).
SELF_UPDATE=true
AUTO_UPDATE=$PHOTARIUM_AUTO_UPDATE

S3_ENDPOINT=$endpoint
S3_REGION=$region
S3_PUBLIC_BUCKET=$PHOTARIUM_PUBLIC_BUCKET
S3_PUBLIC_KEY_ID=$PHOTARIUM_S3_KEY_ID
S3_PUBLIC_SECRET=$PHOTARIUM_S3_SECRET
S3_PRIVATE_BUCKET=$PHOTARIUM_PRIVATE_BUCKET
S3_PRIVATE_KEY_ID=${PHOTARIUM_PRIVATE_S3_KEY_ID:-$PHOTARIUM_S3_KEY_ID}
S3_PRIVATE_SECRET=${PHOTARIUM_PRIVATE_S3_SECRET:-$PHOTARIUM_S3_SECRET}
PUBLIC_IMAGE_BASE_URL=$PHOTARIUM_PUBLIC_URL

CLOUDFLARE_API_TOKEN=${PHOTARIUM_CF_API_TOKEN:-}
CLOUDFLARE_ZONE_ID=${PHOTARIUM_CF_ZONE_ID:-}
EOF
  chown root:"$SVC_USER" "$tmp"
  chmod 0640 "$tmp"
  mv "$tmp" "$CONF"
}

# --- download -------------------------------------------------------------------

download() {
  local version=${PHOTARIUM_VERSION:-latest} dir name
  if [[ $version == latest ]]; then
    dir=latest name="photarium-linux-$ARCH.tar.gz"
  else
    version=${version#v}
    dir="v$version" name="photarium-$version-linux-$ARCH.tar.gz"
  fi
  WORK=$(mktemp -d)
  trap 'rm -rf "$WORK"' EXIT
  say "Downloading $name"
  curl -fsSL --retry 3 -o "$WORK/$name" "$DL_BASE/$dir/$name" || die "download failed: $DL_BASE/$dir/$name"
  curl -fsSL --retry 3 -o "$WORK/SHA256SUMS" "$DL_BASE/$dir/SHA256SUMS" || die "download failed: $DL_BASE/$dir/SHA256SUMS"
  (cd "$WORK" && grep -E "  \\*?$name\$" SHA256SUMS | sha256sum --check --status) ||
    die "checksum verification failed for $name — not installing it"
  tar -xzf "$WORK/$name" -C "$WORK"
  PKGDIR=$(find "$WORK" -mindepth 1 -maxdepth 1 -type d -name 'photarium-*' | head -n1)
  [[ -x $PKGDIR/photosd ]] || die "unexpected archive layout"
}

# --- install -------------------------------------------------------------------

create_user() {
  if ! id "$SVC_USER" >/dev/null 2>&1; then
    say "Creating system user $SVC_USER"
    useradd --system --home-dir "$DATA" --no-create-home \
      --shell "$(command -v nologin || echo /usr/sbin/nologin)" "$SVC_USER"
  fi
  install -d -m 0750 -o "$SVC_USER" -g "$SVC_USER" "$DATA"
  # Where photosd stages updates; it must exist for the update path unit to
  # watch it, and belong to the service user.
  install -d -m 0750 -o "$SVC_USER" -g "$SVC_USER" "$DATA/updates"
}

install_files() {
  say "Installing to $PREFIX"
  install -d -m 0755 "$PREFIX"
  local f
  for f in photosd photosctl backupctl; do
    # Copy then rename, so a running photosd is never overwritten in place.
    install -m 0755 "$PKGDIR/$f" "$PREFIX/.$f.new"
    mv -f "$PREFIX/.$f.new" "$PREFIX/$f"
  done
  install -m 0644 "$PKGDIR/photarium.env.example" "$PKGDIR/LICENSE" "$PKGDIR/NOTICE" "$PREFIX/"
  install -m 0644 "$PKGDIR"/systemd/photarium* "$UNIT_DIR/"
  command -v restorecon >/dev/null && restorecon -R "$PREFIX" "$UNIT_DIR"/photarium* 2>/dev/null || true
  systemctl daemon-reload
}

photosctl() {
  runuser -u "$SVC_USER" -- env PHOTARIUM_CONFIG="$CONF" "$PREFIX/photosctl" "$@"
}

open_firewall() {
  if command -v ufw >/dev/null && ufw status 2>/dev/null | grep -q "Status: active"; then
    say "Opening ports 80 and 443 in ufw"
    ufw allow 80/tcp >/dev/null
    ufw allow 443/tcp >/dev/null
  elif command -v firewall-cmd >/dev/null && firewall-cmd --state >/dev/null 2>&1; then
    say "Opening ports 80 and 443 in firewalld"
    firewall-cmd -q --permanent --add-service=http --add-service=https
    firewall-cmd -q --reload
  fi
}

install_cloudflared() {
  if ! command -v cloudflared >/dev/null; then
    say "Installing cloudflared from Cloudflare's package repository"
    case $PKG in
      apt)
        install -d -m 0755 /usr/share/keyrings
        curl -fsSL https://pkg.cloudflare.com/cloudflare-main.gpg -o /usr/share/keyrings/cloudflare-main.gpg
        echo 'deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] https://pkg.cloudflare.com/cloudflared any main' \
          >/etc/apt/sources.list.d/cloudflared.list
        install_packages cloudflared
        ;;
      dnf)
        curl -fsSL https://pkg.cloudflare.com/cloudflared-ascii.repo -o /etc/yum.repos.d/cloudflared.repo
        install_packages cloudflared
        ;;
      *) die "install cloudflared yourself, then re-run: https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/downloads/" ;;
    esac
  fi
  if systemctl is-enabled cloudflared >/dev/null 2>&1; then
    say "cloudflared service already installed; leaving its tunnel as is"
  else
    say "Connecting the Cloudflare Tunnel"
    cloudflared service install "$PHOTARIUM_TUNNEL_TOKEN" >/dev/null
  fi
}

conf_get() { sed -n "s/^$1=//p" "$CONF" | tail -n1; }

wait_until_up() {
  local url tries=0
  if [[ -n $(conf_get TLS_DOMAIN) ]]; then
    local domain
    domain=$(conf_get TLS_DOMAIN)
    domain=${domain%%,*}
    say "Waiting for https://$domain (first start requests a Let's Encrypt certificate)"
    url="https://$domain/api/auth/me"
    while ((tries++ < 30)); do
      curl -fsS -o /dev/null --max-time 10 --resolve "$domain:443:127.0.0.1" "$url" && return 0
      sleep 2
    done
    warn "https://$domain isn't answering yet. Usually the DNS record doesn't point at this server yet, port 80/443 is blocked, or the record is proxied by Cloudflare. Photarium keeps retrying; watch: journalctl -u photarium -f"
    return 1
  fi
  local addr
  addr=$(conf_get HTTP_ADDR)
  addr=${addr:-$LOCAL_HTTP}
  [[ $addr == :* ]] && addr="127.0.0.1$addr"
  url="http://$addr/api/auth/me"
  say "Waiting for Photarium on $addr"
  while ((tries++ < 30)); do
    curl -fsS -o /dev/null --max-time 5 "$url" && return 0
    sleep 1
  done
  warn "Photarium isn't answering on $addr; see: journalctl -u photarium -e"
  return 1
}

print_summary() {
  local version origin
  version=$("$PREFIX/photosd" -version 2>/dev/null | awk '{print $2}')
  origin=$(conf_get WEB_ORIGIN)
  printf '\n%s%sPhotarium %s is installed.%s\n\n' "$G" "$B" "$version" "$N"
  printf '  Site:      %s\n' "$origin"
  if [[ $UPGRADE == 0 ]]; then
    printf '  Admin:     %s/login  (user: %s)\n' "$origin" "$PHOTARIUM_ADMIN_USER"
    if [[ $GENERATED_PASSWORD == 1 ]]; then
      printf '  Password:  %s%s%s   <- generated; save it now, it is not stored anywhere\n' "$B" "$PHOTARIUM_ADMIN_PASSWORD" "$N"
    fi
  fi
  printf '  Config:    %s\n  Data:      %s\n  Logs:      journalctl -u photarium -f\n' "$CONF" "$DATA"
  printf '  Backups:   daily to the private bucket (systemctl list-timers photarium-backup)\n'
  if [[ $UPGRADE == 0 && $PHOTARIUM_TLS == tunnel ]]; then
    printf '\n  Next: in the Cloudflare dashboard > Networking > Tunnels > your tunnel > Routes,\n'
    printf '  add a Published application: %s -> http://localhost:8080\n' "$PHOTARIUM_DOMAIN"
  elif [[ $UPGRADE == 0 && $PHOTARIUM_TLS == proxy ]]; then
    printf '\n  Next: point your reverse proxy for %s at http://%s\n' "$PHOTARIUM_DOMAIN" "$LOCAL_HTTP"
  fi
  printf '\n  Cloudflare and storage recommendations: https://photarium.waxquixotic.com/install.html\n\n'
}

main() {
  if [[ $UPGRADE == 1 ]]; then
    say "Existing install found ($CONF): upgrading, configuration kept"
  fi
  download
  create_user
  install_files

  if [[ $UPGRADE == 1 ]] && ! grep -q '^SELF_UPDATE=' "$CONF"; then
    # An install from before self-update existed: switch it on.
    printf '\n# Updates (added by a later install.sh run)\nSELF_UPDATE=true\nAUTO_UPDATE=idle\n' >>"$CONF"
  fi

  if [[ $UPGRADE == 0 ]]; then
    configure
    # Before the storage check, so a failed check (fixed by editing the
    # config and re-running, which takes the upgrade path) never leaves an
    # install without an admin account.
    say "Setting the admin password for '$PHOTARIUM_ADMIN_USER'"
    printf '%s\n' "$PHOTARIUM_ADMIN_PASSWORD" | photosctl set-password "$PHOTARIUM_ADMIN_USER" >/dev/null
    case $PHOTARIUM_TLS in
      auto) open_firewall ;;
      tunnel) install_cloudflared ;;
    esac
  fi

  systemctl enable -q photarium.service photarium-backup.timer photarium-update.path
  say "Checking storage (write, read and delete a test object in each bucket)"
  if ! photosctl check; then
    print_summary
    die "the storage check above failed, so Photarium was not started. Fix the storage settings in $CONF, then re-run this installer (it keeps your configuration and password)."
  fi

  systemctl restart photarium.service
  systemctl start photarium-backup.timer photarium-update.path
  wait_until_up || true
  print_summary
}

main "$@"
