#!/bin/sh
# Installs autooptm, AutoOptm's command line: optimise a program on your own
# machine (autooptm alone opens the terminal UI), or send it to our GPUs
# (autooptm run --cloud):
#
#   curl -fsSL https://autooptm.com/install.sh | sh
#
# It picks the build for this system (Linux or macOS, x86_64 or arm64), checks
# it against the published SHA256SUMS, and puts the one file, autooptm, in
# ~/.local/bin, with ao-cli beside it as another name for it (the command was
# called ao-cli until 2026-11-02). Nothing else on the machine is changed; no
# root needed.
#
#   AUTOOPTM_INSTALL_DIR=/usr/local/bin   where to put it (default ~/.local/bin)
#   AUTOOPTM_BASE=https://…/dl/autooptm   where to download from
#   (AO_CLI_INSTALL_DIR and AO_CLI_BASE, the old names, still work)
#
# Everything is inside main(), run on the last line: a download cut short
# runs nothing.
set -eu

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

	case "$(uname -s)" in
	Linux) os=linux ;;
	Darwin) os=darwin ;;
	MINGW* | MSYS* | CYGWIN* | Windows_NT) die "Windows is not supported yet; run this inside WSL (Linux) instead" ;;
	*) die "no build for $(uname -s); builds exist for Linux and macOS" ;;
	esac
	case "$(uname -m)" in
	x86_64 | amd64) arch=amd64 ;;
	aarch64 | arm64) arch=arm64 ;;
	*) die "no build for $(uname -m); builds exist for x86_64 and arm64" ;;
	esac

	if command -v curl >/dev/null 2>&1; then
		get() { curl -fsSL --retry 2 -o "$2" "$1"; }
	elif command -v wget >/dev/null 2>&1; then
		get() { wget -q -O "$2" "$1"; }
	else
		die "needs curl or wget"
	fi
	if command -v sha256sum >/dev/null 2>&1; then
		sum() { sha256sum "$1" | cut -d' ' -f1; }
	elif command -v shasum >/dev/null 2>&1; then
		sum() { shasum -a 256 "$1" | cut -d' ' -f1; }
	else
		die "needs sha256sum or shasum to check the download"
	fi

	tmp=$(mktemp -d 2>/dev/null || mktemp -d -t autooptm)
	trap 'rm -rf "$tmp"' EXIT INT TERM

	# The site first, then its dev copy (where a new build lands before it is
	# released); the first that names a version is used for every file.
	# An old .../dl/ao-cli base (the name until 2026-11-02) is the same place's
	# .../dl/autooptm.
	base=""
	for b in ${AUTOOPTM_BASE:-${AO_CLI_BASE:-https://autooptm.com/dl/autooptm https://dev.autooptm.com/dl/autooptm}}; do
		case $b in */dl/ao-cli | */dl/ao-cli/) b=${b%/dl/ao-cli*}/dl/autooptm ;; esac
		if get "$b/VERSION" "$tmp/VERSION" 2>/dev/null && grep -q '^v' "$tmp/VERSION"; then
			base=$b
			break
		fi
	done
	[ -n "$base" ] || die "could not reach the download site; check the network, or set AUTOOPTM_BASE"
	version=$(head -n1 "$tmp/VERSION")
	file="autooptm-$version-$os-$arch.tar.gz"

	say "autooptm $version for $os/$arch"
	get "$base/$file" "$tmp/$file" || die "download failed: $base/$file"
	get "$base/SHA256SUMS" "$tmp/SHA256SUMS" || die "download failed: $base/SHA256SUMS"
	want=$(awk -v f="$file" '$2 == f { print $1 }' "$tmp/SHA256SUMS")
	[ -n "$want" ] || die "$file is not in SHA256SUMS"
	have=$(sum "$tmp/$file")
	[ "$want" = "$have" ] || die "checksum mismatch for $file (expected $want, got $have); nothing was installed"
	say "  checksum ok"

	tar -xzf "$tmp/$file" -C "$tmp" autooptm
	dir=${AUTOOPTM_INSTALL_DIR:-${AO_CLI_INSTALL_DIR:-$HOME/.local/bin}}
	mkdir -p "$dir" || die "cannot create $dir"
	# Into place by rename: an autooptm that is running keeps its old file.
	cp "$tmp/autooptm" "$dir/.autooptm.new" && chmod 755 "$dir/.autooptm.new" && mv -f "$dir/.autooptm.new" "$dir/autooptm" ||
		die "cannot write $dir (set AUTOOPTM_INSTALL_DIR to a directory you can write)"
	# The old name runs the same file: what was written down with it still works.
	ln -sf autooptm "$dir/.ao-cli.new" && mv -f "$dir/.ao-cli.new" "$dir/ao-cli" || true
	say "  installed $dir/autooptm (ao-cli is another name for it)"
	# The pip package installed a command of the same name, which would come
	# first on PATH and is not this one.
	if old=$(command -v autooptm 2>/dev/null) && [ "$old" != "$dir/autooptm" ]; then
		say ""
		say "another autooptm comes first on your PATH: $old"
		say "  (the old Python package; remove it with: pipx uninstall autooptm, or pip uninstall autooptm)"
	fi

	case ":$PATH:" in
	*":$dir:"*) run=autooptm ;;
	*)
		run="$dir/autooptm"
		say ""
		say "$dir is not on your PATH. Add it (then open a new terminal):"
		say "  echo 'export PATH=\"$dir:\$PATH\"' >> ~/.bashrc   # or ~/.zshrc"
		;;
	esac
	say ""
	"$dir/autooptm" version 2>/dev/null | sed 's/^/  /' || true
	say ""
	say "next:"
	say "  cd your-project && $run      # the terminal UI; it signs you in first"
	say "  $run run --cloud .           # or send the project to our GPUs"
}

main "$@"
