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

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

# PostHog ingestion for the unified PLG project (235654). Public write-only key,
# safe to ship in a public install script. Override with TPC_POSTHOG_KEY.
TPC_POSTHOG_KEY="${TPC_POSTHOG_KEY:-phc_6FJrNsFpdaEsDB7VrpRb3XoZ7aSCKpS2jhFRPAZGoW4}"
TPC_POSTHOG_ENDPOINT="${TPC_POSTHOG_ENDPOINT:-https://us.i.posthog.com}"
TPC_STATE_DIR="${TPC_STATE_DIR:-${HOME}/.tpc}"

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
}

# is_optout_set treats any value other than 0/false/no as opted out (bash 3.2
# compatible — no ${var,,}).
is_optout_set() {
	case "$1" in
		""|0|false|FALSE|False|no|NO) return 1 ;;
		*) return 0 ;;
	esac
}

telemetry_disabled() {
	is_optout_set "${DO_NOT_TRACK:-}" && return 0
	is_optout_set "${TPC_DO_NOT_TRACK:-}" && return 0
	[[ -n "${CI:-}" ]]
}

# ensure_anonymous_id mirrors telemetry/identity.go: a persistent id under
# ~/.tpc shared by install, first run, and login so the timeline stitches.
# Best-effort: every step is guarded so a filesystem error degrades telemetry
# (empty/absent id) instead of tripping `set -e` and aborting the install.
ensure_anonymous_id() {
	local path="${TPC_STATE_DIR}/anonymous_id"
	if [[ -s "${path}" ]]; then
		# Emit the persisted id; on a read error degrade quietly (return 0)
		# rather than letting a non-zero status escape under `set -e`.
		tr -d '[:space:]' <"${path}" 2>/dev/null || return 0
		return 0
	fi

	local id=""
	if command -v uuidgen >/dev/null 2>&1; then
		id="$(uuidgen 2>/dev/null | tr 'A-Z' 'a-z')" || id=""
	elif [[ -r /proc/sys/kernel/random/uuid ]]; then
		id="$(cat /proc/sys/kernel/random/uuid 2>/dev/null)" || id=""
	else
		id="$(od -An -N16 -tx1 /dev/urandom 2>/dev/null | tr -d ' \n')" || id=""
	fi
	[[ -z "${id}" ]] && return 0

	# Persist is best-effort; if the state dir/file can't be written we still
	# emit the in-memory id so this install stitches, and never abort.
	mkdir -p "${TPC_STATE_DIR}" 2>/dev/null || true
	printf '%s\n' "${id}" >"${path}" 2>/dev/null || true
	printf '%s' "${id}"
	return 0
}

# track_install fires a best-effort cli_install event. Never blocks or fails the
# install: backgrounded, short timeout, all output suppressed.
track_install() {
	local version="$1" os="$2" arch="$3"
	telemetry_disabled && return 0
	command -v curl >/dev/null 2>&1 || return 0

	# Telemetry is best-effort: a failure obtaining the id must never abort the
	# install under `set -e`, so swallow any non-zero status here too.
	local anon=""
	anon="$(ensure_anonymous_id)" || anon=""
	[[ -z "${anon}" ]] && return 0

	local payload
	payload="$(printf '{"api_key":"%s","event":"cli_install","distinct_id":"%s","properties":{"app_area":"cli","feature":"cli","os":"%s","arch":"%s","version":"%s","channel":"%s","install_method":"shell"}}' \
		"${TPC_POSTHOG_KEY}" "${anon}" "${os}" "${arch}" "${version}" "${TPC_CHANNEL}")"

	(curl -fsS -m 3 -X POST "${TPC_POSTHOG_ENDPOINT}/i/v0/e/" \
		-H 'Content-Type: application/json' \
		-d "${payload}" >/dev/null 2>&1 || true) &
}

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"
	track_install "${version}" "${os}" "${arch}"
	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."
	say "Install the accompanying GEO agent skill with:"
	say "  tpc skills install"
}

main "$@"
