#!/bin/sh
# Install the togglecraft CLI.
#
#   curl -fsSL https://get.togglecraft.io/install.sh | sh
#
# Environment:
#   TOGGLECRAFT_VERSION       version to install (default: latest)
#   TOGGLECRAFT_INSTALL_DIR   where to put the binary (default: ~/.togglecraft/bin)
#   TOGGLECRAFT_INSTALL_BASE  download site (default: https://get.togglecraft.io)
#
# The archive's SHA-256 checksum is verified before anything is installed.
set -eu

base="${TOGGLECRAFT_INSTALL_BASE:-https://get.togglecraft.io}"
dir="${TOGGLECRAFT_INSTALL_DIR:-$HOME/.togglecraft/bin}"

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

case "$(uname -s)" in
Linux) os=unknown-linux-musl ;;
Darwin) os=apple-darwin ;;
*) fail "unsupported operating system $(uname -s); Linux and macOS are supported" ;;
esac
case "$(uname -m)" in
x86_64 | amd64) arch=x86_64 ;;
arm64 | aarch64) arch=aarch64 ;;
*) fail "unsupported CPU $(uname -m); x86_64 and arm64 are supported" ;;
esac
target="$arch-$os"

if command -v curl >/dev/null 2>&1; then
	fetch() { curl --proto '=https' --tlsv1.2 -fsSL "$1" -o "$2"; }
	case "$base" in http://localhost* | http://127.0.0.1*)
		fetch() { curl -fsSL "$1" -o "$2"; } ;;
	esac
elif command -v wget >/dev/null 2>&1; then
	fetch() { wget -q -O "$2" "$1"; }
else
	fail "curl or wget is required"
fi
if command -v sha256sum >/dev/null 2>&1; then
	sha() { sha256sum "$1" | cut -d' ' -f1; }
elif command -v shasum >/dev/null 2>&1; then
	sha() { shasum -a 256 "$1" | cut -d' ' -f1; }
else
	fail "sha256sum or shasum is required to verify the download"
fi

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

version="${TOGGLECRAFT_VERSION:-}"
if [ -z "$version" ]; then
	fetch "$base/latest.json" "$tmp/latest.json" || fail "could not reach $base"
	version="$(sed -n 's/.*"version"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' "$tmp/latest.json")"
	[ -n "$version" ] || fail "could not read the latest version from $base/latest.json"
fi
case "$version" in
*[!0-9A-Za-z.+-]*) fail "invalid version $version" ;;
esac

archive="togglecraft-$version-$target.tar.gz"
fetch "$base/v$version/$archive" "$tmp/$archive" || fail "no $target build for version $version"
fetch "$base/v$version/$archive.sha256" "$tmp/$archive.sha256" || fail "missing checksum for $archive"
expected="$(cut -d' ' -f1 <"$tmp/$archive.sha256")"
actual="$(sha "$tmp/$archive")"
[ "$expected" = "$actual" ] || fail "checksum mismatch for $archive (expected $expected, got $actual); nothing was installed"

tar -xzf "$tmp/$archive" -C "$tmp"
[ -f "$tmp/togglecraft" ] || fail "archive did not contain the togglecraft binary"
mkdir -p "$dir"
# Replace atomically so a running copy is never half-written.
cp "$tmp/togglecraft" "$dir/.togglecraft.new"
chmod 755 "$dir/.togglecraft.new"
mv -f "$dir/.togglecraft.new" "$dir/togglecraft"

printf 'Installed togglecraft %s to %s/togglecraft\n' "$version" "$dir"
case ":$PATH:" in
*":$dir:"*) ;;
*)
	printf '\nAdd it to your PATH, for example:\n  echo '\''export PATH="%s:$PATH"'\'' >> ~/.profile\n' "$dir"
	;;
esac
printf '\nNext: togglecraft login\n'
