#!/usr/bin/env bash
set -euo pipefail

TPC_INSTALL_BASE_URL="${TPC_INSTALL_BASE_URL:-https://cli.promptingco.com}"
TPC_CHANNEL="${TPC_CHANNEL:-stable}"

say() {
	printf '%s\n' "$*"
}

fail() {
	say "error: $*" >&2
	exit 1
}

detect_os() {
	case "$(uname -s)" in
		Darwin)
			printf 'darwin'
			;;
		Linux)
			printf 'linux'
			;;
		*)
			fail "unsupported operating system: $(uname -s)"
			;;
	esac
}

detect_arch() {
	case "$(uname -m)" in
		x86_64|amd64)
			printf 'amd64'
			;;
		arm64|aarch64)
			printf 'arm64'
			;;
		*)
			fail "unsupported architecture: $(uname -m)"
			;;
	esac
}

compute_sha256() {
	if command -v sha256sum >/dev/null 2>&1; then
		sha256sum "$1" | awk '{print $1}'
		return
	fi

	if command -v shasum >/dev/null 2>&1; then
		shasum -a 256 "$1" | awk '{print $1}'
		return
	fi

	if command -v openssl >/dev/null 2>&1; then
		openssl dgst -sha256 "$1" | awk '{print $NF}'
		return
	fi

	fail "missing checksum utility (need sha256sum, shasum, or openssl)"
}

resolve_version() {
	if [[ -n "${TPC_VERSION:-}" ]]; then
		printf '%s' "${TPC_VERSION}"
		return
	fi

	local metadata_path="/tpc/latest.json"
	if [[ "${TPC_CHANNEL}" != "stable" ]]; then
		metadata_path="/tpc/latest-${TPC_CHANNEL}.json"
	fi

	local metadata
	if ! metadata="$(curl -fsSL "${TPC_INSTALL_BASE_URL}${metadata_path}")"; then
		if [[ "${TPC_CHANNEL}" = "stable" ]]; then
			fail "unable to resolve latest stable version. Use TPC_VERSION=<version> for prereleases."
		fi
		fail "unable to resolve latest ${TPC_CHANNEL} version"
	fi

	local version
	version="$(
		printf '%s' "${metadata}" |
			tr -d '\n' |
			sed -nE 's/.*"version"[[:space:]]*:[[:space:]]*"([^"]+)".*/\1/p'
	)"

	if [[ -z "${version}" ]]; then
		fail "failed to parse version metadata from ${metadata_path}"
	fi

	printf '%s' "${version}"
}

resolve_install_dir() {
	if [[ -n "${TPC_INSTALL_DIR:-}" ]]; then
		printf '%s' "${TPC_INSTALL_DIR}"
		return
	fi

	if [[ -d "${HOME}/.local/bin" || -d "${HOME}/.local" ]]; then
		printf '%s' "${HOME}/.local/bin"
		return
	fi

	printf '%s' "${HOME}/.tpc/bin"
}

main() {
	local version os arch artifact install_dir tmpdir cleanup_tmpdir archive_url checksums_url expected actual

	version="$(resolve_version)"
	os="$(detect_os)"
	arch="$(detect_arch)"
	artifact="tpc_${version}_${os}_${arch}.tar.gz"
	install_dir="$(resolve_install_dir)"
	tmpdir="$(mktemp -d)"
	cleanup_tmpdir="${tmpdir}"
	trap 'rm -rf "${cleanup_tmpdir:-}"' EXIT

	archive_url="${TPC_INSTALL_BASE_URL}/tpc/${version}/${artifact}"
	checksums_url="${TPC_INSTALL_BASE_URL}/tpc/${version}/checksums.txt"

	say "Installing tpc ${version} for ${os}/${arch}"
	curl -fsSL "${archive_url}" -o "${tmpdir}/${artifact}"
	curl -fsSL "${checksums_url}" -o "${tmpdir}/checksums.txt"

	expected="$(
		grep "  ${artifact}\$" "${tmpdir}/checksums.txt" | awk '{print $1}'
	)"
	if [[ -z "${expected}" ]]; then
		fail "checksum entry not found for ${artifact}"
	fi

	actual="$(compute_sha256 "${tmpdir}/${artifact}")"
	if [[ "${expected}" != "${actual}" ]]; then
		fail "checksum verification failed for ${artifact}"
	fi

	tar -xzf "${tmpdir}/${artifact}" -C "${tmpdir}"
	mkdir -p "${install_dir}"
	install -m 0755 "${tmpdir}/tpc" "${install_dir}/tpc"

	say "Installed to ${install_dir}/tpc"
	if [[ ":${PATH}:" != *":${install_dir}:"* ]]; then
		say "Add ${install_dir} to your PATH to invoke tpc directly."
	fi
	say "Run 'tpc --version' to verify the installation."
}

main "$@"
