#!/bin/sh
set -eu

base_url=https://get.ortam.dev
version=
bin_dir=${HOME:+$HOME/.local/bin}

usage() {
	cat <<'USAGE'
usage: install.sh [--version 0.1.0-alpha.N] [--bin-dir DIRECTORY]

Install the latest qualified Ortam CLI, or reinstall a specific retained
private-alpha version. The default destination is $HOME/.local/bin.
USAGE
}

while [ "$#" -gt 0 ]; do
	case "$1" in
		--version)
			[ "$#" -ge 2 ] || { echo "--version requires a value" >&2; exit 2; }
			version=$2
			shift 2
			;;
		--bin-dir)
			[ "$#" -ge 2 ] || { echo "--bin-dir requires a value" >&2; exit 2; }
			bin_dir=$2
			shift 2
			;;
		-h|--help)
			usage
			exit 0
			;;
		*) echo "unknown argument: $1" >&2; usage >&2; exit 2 ;;
	esac
done

[ -n "$bin_dir" ] || {
	echo "HOME is unset; supply --bin-dir DIRECTORY" >&2
	exit 2
}
for command in awk curl grep install mktemp mv tar uname; do
	command -v "$command" >/dev/null || {
		echo "required installation command is unavailable: $command" >&2
		exit 1
	}
done

stage=$(mktemp -d "${TMPDIR:-/tmp}/ortam-install.XXXXXX")
cleanup() { find "$stage" -depth -delete; }
trap cleanup EXIT HUP INT TERM
umask 077

if [ -z "$version" ]; then
	curl --fail --silent --show-error --location --retry 3 \
		"$base_url/latest" > "$stage/latest"
	version=$(tr -d '\r\n' < "$stage/latest")
fi
printf '%s\n' "$version" | grep -Eq '^0[.]1[.]0-alpha[.][1-9][0-9]*$' || {
	echo "distribution returned an invalid private-alpha version" >&2
	exit 1
}

case "$(uname -s):$(uname -m)" in
	Darwin:arm64) target_os=darwin; target_arch=arm64 ;;
	Linux:x86_64|Linux:amd64) target_os=linux; target_arch=amd64 ;;
	*)
		echo "unsupported platform: $(uname -s) $(uname -m); supported: macOS arm64, Linux x86-64" >&2
		exit 1
		;;
esac

release_url=$base_url/releases/$version
filename="ortam_${version}_${target_os}_${target_arch}.tar.gz"
# manifest.json is the immutable commit marker. Its absence makes partial
# versioned uploads ineligible for installation.
curl --fail --silent --show-error --location --retry 3 \
	"$release_url/manifest.json" > "$stage/manifest.json"
curl --fail --silent --show-error --location --retry 3 \
	"$release_url/SHA256SUMS" > "$stage/SHA256SUMS"
curl --fail --silent --show-error --location --retry 3 \
	"$release_url/$filename" > "$stage/$filename"

expected=$(awk -v filename="$filename" '$2 == filename { print $1 }' "$stage/SHA256SUMS")
printf '%s\n' "$expected" | grep -Eq '^[0-9a-f]{64}$' || {
	echo "release checksums do not contain one valid digest for $filename" >&2
	exit 1
}
if command -v sha256sum >/dev/null; then
	actual=$(sha256sum "$stage/$filename" | awk '{print $1}')
elif command -v shasum >/dev/null; then
	actual=$(shasum -a 256 "$stage/$filename" | awk '{print $1}')
else
	echo "sha256sum or shasum is required to verify the Ortam CLI" >&2
	exit 1
fi
[ "$actual" = "$expected" ] || {
	echo "downloaded Ortam CLI checksum does not match its immutable release" >&2
	exit 1
}

mkdir "$stage/extract"
tar -xzf "$stage/$filename" -C "$stage/extract"
[ "$("$stage/extract/ortam" version)" = "ortam $version" ] || {
	echo "downloaded Ortam CLI reports the wrong release identity" >&2
	exit 1
}
mkdir -p "$bin_dir"
temporary_target=$bin_dir/.ortam-install-$$
install -m 0755 "$stage/extract/ortam" "$temporary_target"
mv -f "$temporary_target" "$bin_dir/ortam"
echo "Installed Ortam $version to $bin_dir/ortam"
case ":${PATH:-}:" in
	*:"$bin_dir":*) : ;;
	*) echo "Add $bin_dir to PATH before running ortam." ;;
esac
