#!/usr/bin/env bash
# Installs a Keal engine from a published release:
#
#   curl -fsSL https://registry.keal.sh/downloads/install-engine.sh | sudo bash
#   curl -fsSL https://registry.keal.sh/downloads/install-engine.sh | sudo bash -s -- --admin you
#
# It fetches the release, checks its signature and checksum, unpacks it and
# runs its keal-install, with whatever options it was given (keal-install
# --help says which). A release is signed with the key whose public half is
# below, the same as support/keal-release.pub.
#
# Settings (environment):
#   KEAL_VERSION    the release to install, e.g. v0.7.0 (default: the latest)
#   KEAL_DOWNLOADS  where releases are (default: https://registry.keal.sh/downloads)
set -euo pipefail

# All in a function, called on the last line: bash reads a piped script as it
# runs it, so a command that read stdin would otherwise eat the rest of it -
# and a download cut short runs nothing.
main() {
DOWNLOADS="${KEAL_DOWNLOADS:-https://registry.keal.sh/downloads}"
DOWNLOADS="${DOWNLOADS%/}"
PUBKEY='-----BEGIN PUBLIC KEY-----
MCowBQYDK2VwAyEAKFe927p361EbcxfMWDmsntRN0zdslwOZUUrWapO3jGk=
-----END PUBLIC KEY-----'

die() { echo "install-engine: $*" >&2; exit 1; }
[[ $EUID -eq 0 ]] || die "run it as root: curl -fsSL $DOWNLOADS/install-engine.sh | sudo bash"
for tool in curl openssl sha256sum tar; do
    command -v "$tool" >/dev/null || die "it needs $tool"
done

VERSION="${KEAL_VERSION:-}"
if [[ -z "$VERSION" ]]; then
    VERSION="$(curl -fsSL "$DOWNLOADS/latest")" || die "could not ask $DOWNLOADS which release is the latest"
fi
VERSION="$(printf '%s' "$VERSION" | tr -d '[:space:]')"
[[ "$VERSION" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-[0-9]+-g[0-9a-f]+)?$ ]] || die "not a release version: $VERSION"

tmp="$(mktemp -d /tmp/keal-release.XXXXXX)"
trap 'rm -rf "$tmp"' EXIT
tarball="keal-$VERSION.tar.gz"
echo "Fetching Keal $VERSION from $DOWNLOADS"
for f in "$tarball" SHA256SUMS SHA256SUMS.sig; do
    curl -fsSL -o "$tmp/$f" "$DOWNLOADS/$VERSION/$f" || die "could not fetch $DOWNLOADS/$VERSION/$f"
done

printf '%s\n' "$PUBKEY" > "$tmp/keal-release.pub"
openssl pkeyutl -verify -pubin -inkey "$tmp/keal-release.pub" -rawin \
    -in "$tmp/SHA256SUMS" -sigfile "$tmp/SHA256SUMS.sig" >/dev/null 2>&1 \
    || die "the release's signature does not check out - not installing it"
(cd "$tmp" && grep " ${tarball}\$" SHA256SUMS | sha256sum -c --status) \
    || die "$tarball does not match its checksum - not installing it"
echo "Signature and checksum check out"

tar -xzf "$tmp/$tarball" -C "$tmp"
[[ -x "$tmp/keal/support/keal-install" ]] || die "$tarball holds no keal/support/keal-install"
# Not exec: the trap removes the unpacked release once it is installed -
# keal-install copies it into place.
bash "$tmp/keal/support/keal-install" "$@"
}

main "$@" < /dev/null
