#!/bin/sh
# HiTechCloud Panel - installer bootstrap.
#
#   curl -sSL https://hitechcloud.org | bash -s -- [options]
#   bash INSTALL.sh [options]          (--help lists them)
#
# This stays a shell file for one reason: it is what an operator pipes from
# curl into a shell on a machine that has nothing installed yet. It does the
# least that needs: fetch the installer - hitechcloudcli, a Rust binary - for
# this machine's architecture from the mirror, check the release's SHA256SUMS
# against its Ed25519 signature (SHA256SUMS.sig), check the binary against
# SHA256SUMS, and hand over to `hitechcloudcli server-install` with the same
# arguments. Every step of the installation is in that command
# (hitechcloudcli/server/install.rs), and so are --dry-run, --adopt and
# --reinstall. HITECHCLOUD_MIRROR, HITECHCLOUD_VERSION (or --version) and
# HITECHCLOUD_INSTALLER (a hitechcloudcli already on this machine) say where
# the installer comes from.
set -eu
[ "$(id -u)" = 0 ] || { echo "Run as root: sudo bash INSTALL.sh" >&2; exit 1; }
[ -n "${HITECHCLOUD_INSTALLER:-}" ] && exec "$HITECHCLOUD_INSTALLER" --direct server-install "$@"
mirror="${HITECHCLOUD_MIRROR:-https://mirrors.hitechcloud.org}" release="${HITECHCLOUD_VERSION:-latest}" prev=""
for a in "$@"; do
    case "$prev" in --version) release="$a" ;; esac
    case "$a" in --version=*) release="${a#--version=}" ;; esac
    prev="$a"
done
case "$(uname -m)" in
    x86_64|amd64) arch=amd64 ;;
    aarch64|arm64) arch=arm64 ;;
    *) echo "Unsupported architecture: $(uname -m). The panel ships amd64 and arm64 builds." >&2; exit 1 ;;
esac
dir=$(mktemp -d) base="$mirror/releases/${release#v}" asset="hitechcloudcli-linux-$arch"
# The binary, SHA256SUMS and its signature all come from the same mirror, so
# SHA256SUMS alone only proves the download was not truncated: whoever controls
# the mirror (or the path to it) can rewrite both. The signature is what ties
# the release to the owner's key, so it is checked before SHA256SUMS is
# believed, and anything missing or wrong stops here with nothing installed.
# openssl verifies it because it is the one tool every supported distribution
# ships that does Ed25519 (1.1.1 or later); the CLI checks the same signature
# again on every `update` (hitechcloudcli/update/full.rs).
command -v openssl >/dev/null 2>&1 || {
    echo "openssl is needed to verify the release signature. Install it (dnf/apt-get install openssl) and run this again." >&2
    rm -rf "$dir"; exit 1
}
if ! curl -4fsSL --retry 3 --connect-timeout 20 "$base/$asset" -o "$dir/hitechcloudcli" ||
   ! curl -4fsSL --retry 3 --connect-timeout 20 "$base/SHA256SUMS" -o "$dir/SHA256SUMS" ||
   ! curl -4fsSL --retry 3 --connect-timeout 20 "$base/SHA256SUMS.sig" -o "$dir/SHA256SUMS.sig"; then
    echo "Could not download the installer, SHA256SUMS or SHA256SUMS.sig from $base - check this machine's DNS and outbound HTTPS." >&2
    echo "A release without SHA256SUMS.sig is not installed: its checksums cannot be trusted." >&2
    rm -rf "$dir"; exit 1
fi
# The release key: the same key, and key id, as RELEASE_KEYS in
# hitechcloudcli/modules/keys.rs ("htc-ed25519 WBbwbpd5...Dr+c=
# hitechcloud-release-2026", id e36116ab8dcff9ab = first 16 hex of the
# SHA-256 of the raw key). Here it is the same 32 raw bytes wrapped as an
# X.509 SubjectPublicKeyInfo PEM, the form openssl reads. Rotating the key
# means changing both places.
release_key_id=e36116ab8dcff9ab
cat > "$dir/release.pem" <<'PEM'
-----BEGIN PUBLIC KEY-----
MCowBQYDK2VwAyEAWBbwbpd57b0Cw9Wem6QkzqI/PlV1GI7Uey7Xms/Dr+c=
-----END PUBLIC KEY-----
PEM
# SHA256SUMS.sig is one line, `htc-ed25519-sig <key id> <base64 64 bytes>`
# (devtools sign-release), a pure Ed25519 signature over SHA256SUMS's exact
# bytes - hence `pkeyutl -rawin`, with no digest of our own in between.
sig_ok=0
read -r sig_kind sig_id sig_b64 sig_extra < "$dir/SHA256SUMS.sig" || true
if [ "${sig_kind:-}" = htc-ed25519-sig ] && [ "${sig_id:-}" = "$release_key_id" ] && [ -n "${sig_b64:-}" ] && [ -z "${sig_extra:-}" ] &&
   printf '%s' "$sig_b64" | openssl base64 -d -A > "$dir/SHA256SUMS.sig.bin" 2>/dev/null &&
   [ "$(wc -c < "$dir/SHA256SUMS.sig.bin" | tr -d ' ')" = 64 ] &&
   openssl pkeyutl -verify -pubin -inkey "$dir/release.pem" -rawin -in "$dir/SHA256SUMS" -sigfile "$dir/SHA256SUMS.sig.bin" >/dev/null 2>&1; then
    sig_ok=1
fi
if [ "$sig_ok" != 1 ]; then
    echo "The release's SHA256SUMS.sig is missing, malformed, by another key, or does not match SHA256SUMS (release key $release_key_id)." >&2
    echo "The download from $base cannot be trusted. Nothing was installed." >&2
    echo "(openssl 1.1.1 or later is required; check 'openssl version'.)" >&2
    rm -rf "$dir"; exit 1
fi
want=$(awk -v a="$asset" '$2 == a || $2 == "*"a { print $1; exit }' "$dir/SHA256SUMS")
if [ -z "$want" ] || [ "$want" != "$(sha256sum "$dir/hitechcloudcli" | cut -d' ' -f1)" ]; then
    echo "The installer does not match the release's SHA256SUMS. Nothing was installed." >&2
    rm -rf "$dir"; exit 1
fi
chmod 755 "$dir/hitechcloudcli"
HITECHCLOUD_BOOTSTRAP_DIR="$dir" exec "$dir/hitechcloudcli" --direct server-install "$@"
