#!/bin/sh
# Guppi installer — https://github.com/ekristen/guppi
# Usage: curl -sSL https://get.guppi.sh | sh
#
# Environment variables:
#   VERSION       — version to install (default: latest)
#   INSTALL_DIR   — where to put the binary (default: /usr/local/bin or ~/.local/bin)
set -eu

REPO="ekristen/guppi"
BINARY="guppi"
VERSION="${VERSION:-latest}"
INSTALL_DIR="${INSTALL_DIR:-}"

# --- helpers ----------------------------------------------------------------

log() { printf '%s\n' "$@"; }
err() { log "error: $*" >&2; exit 1; }

need() {
  command -v "$1" > /dev/null 2>&1 || err "$1 is required but not found"
}

# --- detect platform --------------------------------------------------------

detect_os() {
  case "$(uname -s)" in
    Linux*)  echo "linux" ;;
    Darwin*) echo "darwin" ;;
    *)       err "unsupported OS: $(uname -s)" ;;
  esac
}

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

# --- resolve version --------------------------------------------------------

resolve_version() {
  if [ "$VERSION" = "latest" ]; then
    # Try stable release first, fall back to any release (including prereleases)
    VERSION=$(curl -sSfL "https://api.github.com/repos/${REPO}/releases/latest" 2>/dev/null \
      | grep '"tag_name"' | head -1 | sed 's/.*"tag_name": *"//;s/".*//' || true)
    if [ -z "$VERSION" ]; then
      VERSION=$(curl -sSfL "https://api.github.com/repos/${REPO}/releases" \
        | grep '"tag_name"' | head -1 | sed 's/.*"tag_name": *"//;s/".*//')
    fi
    [ -n "$VERSION" ] || err "could not determine latest version"
  fi
}

# --- pick install dir -------------------------------------------------------

pick_install_dir() {
  if [ -n "$INSTALL_DIR" ]; then
    return
  fi
  if [ "$(id -u)" = "0" ]; then
    INSTALL_DIR="/usr/local/bin"
  elif [ -d "/usr/local/bin" ] && [ -w "/usr/local/bin" ]; then
    INSTALL_DIR="/usr/local/bin"
  else
    INSTALL_DIR="${HOME}/.local/bin"
  fi
}

# --- main -------------------------------------------------------------------

main() {
  need curl
  need tar

  OS=$(detect_os)
  ARCH=$(detect_arch)
  resolve_version

  ARCHIVE="${BINARY}-${VERSION}-${OS}-${ARCH}.tar.gz"
  URL="https://github.com/${REPO}/releases/download/${VERSION}/${ARCHIVE}"

  pick_install_dir
  mkdir -p "$INSTALL_DIR"

  TEMP_DIR=$(mktemp -d)
  trap 'rm -rf "$TEMP_DIR"' EXIT

  log ""
  log "  Installing ${BINARY} ${VERSION} (${OS}/${ARCH})"
  log "  From: ${URL}"
  log "  To:   ${INSTALL_DIR}/${BINARY}"
  log ""

  curl -sSfL "$URL" -o "${TEMP_DIR}/${ARCHIVE}" \
    || err "download failed — check that ${VERSION} exists at https://github.com/${REPO}/releases"

  tar -xzf "${TEMP_DIR}/${ARCHIVE}" -C "$TEMP_DIR" \
    || err "failed to extract archive"

  if [ -f "${TEMP_DIR}/${BINARY}" ]; then
    install -m 755 "${TEMP_DIR}/${BINARY}" "${INSTALL_DIR}/${BINARY}"
  else
    err "binary '${BINARY}' not found in archive"
  fi

  log "  Installed ${BINARY} ${VERSION} to ${INSTALL_DIR}/${BINARY}"
  log ""

  # Check if install dir is in PATH
  case ":${PATH}:" in
    *":${INSTALL_DIR}:"*) ;;
    *)
      log "  Note: ${INSTALL_DIR} is not in your PATH."
      log "  Add it with: export PATH=\"${INSTALL_DIR}:\$PATH\""
      log ""
      ;;
  esac

  log "  Get started:"
  log "    ${BINARY} server          # start the dashboard"
  log "    ${BINARY} agent-setup     # configure agent hooks"
  log "    ${BINARY} install         # install as a system service"
  log ""
}

main
