#!/bin/sh
set -eu

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

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

command_exists() {
  command -v "$1" >/dev/null 2>&1
}

cyan=""; green=""; bold=""; reset=""
if [ -t 1 ] && [ "$(printenv TERM 2>/dev/null || printf dumb)" != "dumb" ] && ! printenv NO_COLOR >/dev/null 2>&1; then
  cyan=$(printf '\033[36m'); green=$(printf '\033[32m')
  bold=$(printf '\033[1m'); reset=$(printf '\033[0m')
fi
step() {
  printf '  %b%s%b %s\n' "$3" "$1" "$reset" "$2"
}
# ASCII source keeps raw-template bundlers from turning glyphs into literal Unicode escapes.
diamond=$(printf '\342\227\207'); checkmark=$(printf '\342\234\223')
ellipsis=$(printf '\342\200\246'); middot=$(printf '\302\267')

os_name=$(uname -s 2>/dev/null || printf unknown)
arch_name=$(uname -m 2>/dev/null || printf unknown)

case "$os_name" in
  Darwin) platform="macOS"; binary_os="darwin" ;;
  Linux) platform="Linux"; binary_os="linux" ;;
  *) fail "unsupported system: $os_name. Use https://openteam.so/download for other options." ;;
esac

case "$arch_name" in
  x86_64|amd64) architecture="x64" ;;
  arm64|aarch64) architecture="arm64" ;;
  *) fail "unsupported architecture: $arch_name. OpenTeam supports x64 and arm64 hosts." ;;
esac

printf '\n  %bOPENTEAM%b / install\n' "$bold$cyan" "$reset"
say "  $platform $middot $architecture"
say ""

command_exists curl || fail "curl is required to download the OpenTeam CLI."

repository=$(printenv OPENTEAM_REPOSITORY 2>/dev/null || printf raghavpillai/openteam)
cli_version=$(printenv OPENTEAM_VERSION 2>/dev/null || printf latest)
if [ "$cli_version" = "latest" ]; then
  release_json=$(curl -fsSL "https://api.github.com/repos/$repository/releases/latest") ||
    fail "no public OpenTeam release is available yet."
  release_tag=$(printf '%s' "$release_json" | sed -n 's/.*"tag_name"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' | head -n 1)
  [ -n "$release_tag" ] || fail "the latest GitHub release did not include a tag."
else
  case "$cli_version" in
    v*) release_tag="$cli_version" ;;
    *) release_tag="v$cli_version" ;;
  esac
fi

asset_name="openteam-$binary_os-$architecture"
release_base="https://github.com/$repository/releases/download/$release_tag"
temporary_directory=$(mktemp -d 2>/dev/null || mktemp -d -t openteam)
binary_path="$temporary_directory/$asset_name"
checksums_path="$temporary_directory/SHA256SUMS"

cleanup() {
  rm -rf "$temporary_directory"
}
trap cleanup EXIT HUP INT TERM

step "$diamond" "Downloading CLI $release_tag$ellipsis" "$cyan"
# Prefer the gzip copy (about a third of the size); fall back to the raw binary for releases
# that predate it. The checksum below is always verified against the decompressed binary.
if command_exists gunzip && curl -fsL --retry 3 --connect-timeout 15 "$release_base/$asset_name.gz" -o "$binary_path.gz" 2>/dev/null; then
  gunzip -f "$binary_path.gz" || fail "could not decompress $asset_name.gz."
else
  rm -f "$binary_path.gz"
  curl -fsSL --retry 3 --connect-timeout 15 "$release_base/$asset_name" -o "$binary_path" ||
    fail "could not download $asset_name from $release_tag."
fi
curl -fsSL --retry 3 --connect-timeout 15 "$release_base/SHA256SUMS" -o "$checksums_path" ||
  fail "could not download checksums for $release_tag."

expected_checksum=$(awk -v name="$asset_name" '$2 == name || $2 ~ ("/" name "$") { print $1; exit }' "$checksums_path")
[ -n "$expected_checksum" ] || fail "SHA256SUMS does not contain $asset_name."

if command_exists sha256sum; then
  actual_checksum=$(sha256sum "$binary_path" | awk '{print $1}')
elif command_exists shasum; then
  actual_checksum=$(shasum -a 256 "$binary_path" | awk '{print $1}')
else
  fail "sha256sum or shasum is required to verify the download."
fi

[ "$actual_checksum" = "$expected_checksum" ] || fail "the OpenTeam CLI checksum did not match."
step "$checkmark" "Download verified" "$green"
chmod +x "$binary_path"

user_home=$(printenv HOME 2>/dev/null || true)
[ -n "$user_home" ] || fail "HOME is not set. Set OPENTEAM_BIN_DIR to choose where to install the CLI."
bin_directory=$(printenv OPENTEAM_BIN_DIR 2>/dev/null || printf '%s/.local/bin' "$user_home")
mkdir -p "$bin_directory"
installed_binary="$bin_directory/openteam"
if command_exists install; then
  install -m 0755 "$binary_path" "$installed_binary"
else
  cp "$binary_path" "$installed_binary"
  chmod +x "$installed_binary"
fi

step "$checkmark" "CLI installed" "$green"
say "    $installed_binary"
case ":$PATH:" in
  *":$bin_directory:"*) ;;
  *) say "  Add $bin_directory to PATH to run openteam later." ;;
esac

printf '\n  %bSERVER SETUP%b\n\n' "$bold$cyan" "$reset"
# Opening /dev/tty can fail even when it is readable (for example, in CI).
if ( : </dev/tty ) 2>/dev/null; then
  "$installed_binary" install "$@" </dev/tty
  exit $?
fi

# The CLI checks prerequisites before asking for a terminal. Keep it installed
# when setup is blocked, so the user can fix Docker and resume with openteam setup.
"$installed_binary" install "$@" </dev/null
