#!/bin/sh
#
# Cloudflare-hosted installer for cloudarch-debian-upgrader.
# Usage:
#   curl -fsSL https://cloudarch-debian-upgrader.pages.dev/install.sh | sudo bash
#   curl -fsSL https://cloudarch-debian-upgrader.pages.dev/install.sh | sudo bash -s -- --menu
#   curl -fsSL https://cloudarch-debian-upgrader.pages.dev/install.sh | sudo bash -s -- --target 12 --dry-run
#   # custom domain / mirror:
#   curl -fsSL https://<pages-domain>/install.sh | sudo CADU_BASE_URL=https://<pages-domain> sh

set -eu

prog="cloudarch-debian-upgrader"
base_url="${CADU_BASE_URL:-https://cloudarch-debian-upgrader.pages.dev}"
version="${CADU_VERSION:-latest}"
install_dir="${CADU_INSTALL_DIR:-/opt/cloudarch-debian-upgrader}"
bin_dir="${CADU_BIN_DIR:-/usr/local/bin}"

fail() {
  printf 'ERROR: %s\n' "$*" >&2
  exit 1
}

need_cmd() {
  command -v "$1" >/dev/null 2>&1 || fail "missing required command: $1"
}

download() {
  url="$1"
  out="$2"
  if command -v curl >/dev/null 2>&1; then
    curl -fsSL "$url" -o "$out"
  elif command -v wget >/dev/null 2>&1; then
    wget -qO "$out" "$url"
  else
    fail "missing required command: curl or wget"
  fi
}

sha256_file() {
  file="$1"
  if command -v sha256sum >/dev/null 2>&1; then
    sha256sum "$file" | awk '{print $1}'
  elif command -v shasum >/dev/null 2>&1; then
    shasum -a 256 "$file" | awk '{print $1}'
  else
    fail "missing required command: sha256sum or shasum"
  fi
}

need_cmd awk
need_cmd chmod
need_cmd date
need_cmd dirname
need_cmd mktemp
need_cmd mkdir
need_cmd mv
need_cmd rm
need_cmd sed
need_cmd tar

base_url="${base_url%/}"
artifact="${prog}-${version}.tar.gz"
artifact_url="${base_url}/downloads/${artifact}"
sha_url="${artifact_url}.sha256"
artifact_fetch_url="${artifact_url}"
sha_fetch_url="${sha_url}"

if [ "$version" = "latest" ]; then
  cache_bust="$(date -u +%s)"
  artifact_fetch_url="${artifact_url}?v=${cache_bust}"
  sha_fetch_url="${sha_url}?v=${cache_bust}"
fi

tmp_dir="$(mktemp -d)"
trap 'rm -rf "$tmp_dir"' EXIT INT TERM

printf 'Downloading %s\n' "$artifact_url"
download "$artifact_fetch_url" "${tmp_dir}/${artifact}"
download "$sha_fetch_url" "${tmp_dir}/${artifact}.sha256"

expected="$(awk '{print $1}' "${tmp_dir}/${artifact}.sha256")"
actual="$(sha256_file "${tmp_dir}/${artifact}")"
[ "$expected" = "$actual" ] || fail "checksum mismatch for ${artifact}"

mkdir -p "${tmp_dir}/extract"
tar -xzf "${tmp_dir}/${artifact}" -C "${tmp_dir}/extract"
[ -d "${tmp_dir}/extract/${prog}" ] || fail "archive does not contain ${prog}/"

if [ -e "$install_dir" ]; then
  backup_dir="${install_dir}.bak.$(date -u +%Y%m%dT%H%M%SZ)"
  printf 'Backing up existing install to %s\n' "$backup_dir"
  mv "$install_dir" "$backup_dir"
fi

mkdir -p "$(dirname "$install_dir")" "$bin_dir"
mv "${tmp_dir}/extract/${prog}" "$install_dir"
chmod +x "${install_dir}/${prog}.sh"

quote_sh() {
  printf "'"
  printf '%s' "$1" | sed "s/'/'\\\\''/g"
  printf "'"
}

write_wrapper() {
  name="$1"
  {
    printf '#!/bin/sh\n'
    printf 'exec %s/%s.sh "$@"\n' "$(quote_sh "$install_dir")" "$prog"
  } >"${bin_dir}/${name}"
  chmod +x "${bin_dir}/${name}"
}

write_wrapper "${prog}"
write_wrapper "${prog}.sh"
write_wrapper "cadu"

if [ -x "${install_dir}/tools/setup-debian-auto-updates.sh" ]; then
  {
    printf '#!/bin/sh\n'
    printf 'exec %s/tools/setup-debian-auto-updates.sh "$@"\n' "$(quote_sh "$install_dir")"
  } >"${bin_dir}/cadu-auto-updates"
  chmod +x "${bin_dir}/cadu-auto-updates"
fi

printf 'Installed %s to %s\n' "$prog" "$install_dir"
printf 'Commands:\n'
printf '  cadu --version\n'
printf '  cadu\n'
printf '  cadu --target 12 --dry-run\n'
printf '  cadu-auto-updates --security-only\n'
printf '  cadu-auto-updates --status\n'
printf 'Also available: %s, %s.sh\n' "$prog" "$prog"
printf 'One-line run examples:\n'
printf '  curl -fsSL %s/install.sh | sudo bash -s -- --menu\n' "$base_url"
printf '  curl -fsSL %s/install.sh | sudo bash -s -- --target 12 --dry-run\n' "$base_url"

if [ "${1:-}" = "--menu" ]; then
  shift
  printf 'Starting: cadu\n'
  if [ -r /dev/tty ]; then
    exec "${bin_dir}/cadu" "$@" </dev/tty
  fi
  exec "${bin_dir}/cadu" "$@"
fi

if [ "$#" -gt 0 ]; then
  printf 'Running: cadu %s\n' "$*"
  exec "${bin_dir}/cadu" "$@"
fi
