#!/usr/bin/env bash
#
# Install the sema4 CLI:
#
#     curl willc.sh/sema4 | bash
#
# Downloads the prebuilt binary for this OS and architecture from
# https://willc.sh/dist/sema4/<version>/, verifies it against the SHA256SUMS
# published next to it, and installs it as ~/.local/bin/sema4.
#
# Environment:
#   SEMA4_VERSION      pin a build (default: whatever /dist/sema4/VERSION says)
#   SEMA4_INSTALL_DIR  directory for the binary (default: ~/.local/bin)
#
# Only the current build is kept under /dist/sema4, so a pinned SEMA4_VERSION
# stops resolving once a newer build is published.

set -euo pipefail

base=${SEMA4_BASE_URL:-https://willc.sh/dist/sema4}
install_dir=${SEMA4_INSTALL_DIR:-$HOME/.local/bin}

say() { printf 'sema4 install: %s\n' "$*" >&2; }
die() { say "$*"; exit 1; }

command -v curl >/dev/null || die 'curl is required'

case "$(uname -s)" in
	Darwin) os=darwin;;
	Linux) os=linux;;
	*) die "unsupported OS $(uname -s): builds exist for darwin and linux";;
esac
case "$(uname -m)" in
	x86_64|amd64) arch=amd64;;
	arm64|aarch64) arch=arm64;;
	*) die "unsupported architecture $(uname -m): builds exist for amd64 and arm64";;
esac

if [[ -n ${SEMA4_VERSION:-} ]]; then
	version=$SEMA4_VERSION
else
	version=$(curl -fsSL --retry 3 "$base/VERSION") || die "could not read $base/VERSION"
	version=${version%%[[:space:]]*}
fi
[[ -n $version ]] || die 'empty version'

asset=sema4-$os-$arch
url=$base/$version/$asset

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

say "downloading $url"
curl -fsSL --retry 3 -o "$tmp/$asset" "$url" || die "download failed: $url"
curl -fsSL --retry 3 -o "$tmp/SHA256SUMS" "$base/$version/SHA256SUMS" \
	|| die "could not fetch $base/$version/SHA256SUMS"

expected=$(awk -v f="$asset" '$2 == f { print $1 }' "$tmp/SHA256SUMS")
[[ -n $expected ]] || die "SHA256SUMS has no entry for $asset"
if command -v sha256sum >/dev/null; then
	actual=$(sha256sum "$tmp/$asset" | awk '{ print $1 }')
elif command -v shasum >/dev/null; then
	actual=$(shasum -a 256 "$tmp/$asset" | awk '{ print $1 }')
else
	die 'need sha256sum or shasum to verify the download'
fi
[[ $actual == "$expected" ]] \
	|| die "checksum mismatch for $asset (expected $expected, got $actual)"

mkdir -p "$install_dir"
chmod 0755 "$tmp/$asset"
mv -f "$tmp/$asset" "$install_dir/sema4"
say "installed $install_dir/sema4 ($version)"

case ":$PATH:" in
	*":$install_dir:"*) ;;
	*) say "add it to your PATH:  export PATH=\"$install_dir:\$PATH\"";;
esac
say 'shell completion (optional):  sema4 cli completion install zsh   # or fish'
