#!/usr/bin/env bash
# Okal CLI installer — downloads the native binary for your platform.
# Quick install: curl -fsSL https://get.okal.io | bash
set -euo pipefail

OKAL_DOWNLOAD_BASE_URL="${OKAL_DOWNLOAD_BASE_URL:-https://get.okal.io}"
OKAL_INSTALL_DIR="${OKAL_INSTALL_DIR:-/usr/local/bin}"
OKAL_FALLBACK_DIR="${OKAL_FALLBACK_DIR:-$HOME/.local/bin}"

detect_platform() {
  case "$(uname -s)" in Darwin) OS="darwin" ;; Linux) OS="linux" ;; *) echo "Unsupported OS: $(uname -s)"; exit 1 ;; esac
  case "$(uname -m)" in x86_64) ARCH="amd64" ;; aarch64|arm64) ARCH="arm64" ;; *) echo "Unsupported arch: $(uname -m)"; exit 1 ;; esac
}

# ---------------------------------------------------------------------------
# Helpers
# ---------------------------------------------------------------------------
info()  { printf "${BOLD}${CYAN}==> %s${RESET}\n" "$*"; }
ok()    { printf "${BOLD}${GREEN}✓ %s${RESET}\n" "$*"; }
warn()  { printf "${BOLD}${YELLOW}⚠ %s${RESET}\n" "$*" >&2; }
fail()  { printf "${BOLD}${RED}✗ %s${RESET}\n" "$*" >&2; exit 1; }

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

running_in_ssh_session() {
  [ -n "${SSH_CONNECTION:-}" ] || [ -n "${SSH_CLIENT:-}" ] || [ -n "${SSH_TTY:-}" ]
}

print_remote_server_token_hint() {
  if ! running_in_ssh_session; then
    return
  fi

  printf "  ${BOLD}Looks like a remote/SSH session.${RESET} Browser login may not be able to call back to this machine's localhost.\n"
  printf "  Token login is usually simpler here:\n"
  printf "     1. On your local computer, open ${CYAN}https://okal.io/settings?tab=tokens${RESET}\n"
  printf "        and create a token under ${BOLD}Settings > API Tokens${RESET}.\n"
  printf "     2. On this server, run:\n"
  printf "        ${CYAN}okal login --token <YOUR_TOKEN>${RESET}\n"
  printf "        ${CYAN}okal daemon start${RESET}\n"
  printf "\n"
}

# verify_sha256 downloads SHA256SUMS next to the binary and checks the hash.
# This protects against CDN compromise and MITM on non-TLS hops.
verify_sha256() {
  local file="$1" version="$2"
  local sums_url="${OKAL_DOWNLOAD_BASE_URL}/${version}/SHA256SUMS"
  local sums_file="$tmp/SHA256SUMS"
  curl -fsSL "$sums_url" -o "$sums_file" || {
    echo "WARN: could not fetch SHA256SUMS — skipping verification (insecure)" >&2
    return 0
  }
  # Format: "<sha>  filename" (sha256sum output, two-space separator)
  local expected
  expected=$(awk -v f="${OS}-${ARCH}/okal" '$2 == f { print $1 }' "$sums_file")
  if [ -z "$expected" ]; then
    echo "WARN: no entry for ${OS}-${ARCH}/okal in SHA256SUMS — skipping" >&2
    return 0
  fi
  local actual
  actual=$(sha256sum "$file" | awk '{ print $1 }')
  if [ "$expected" != "$actual" ]; then
    echo "ERROR: SHA256 mismatch for $file" >&2
    echo "  expected: $expected" >&2
    echo "  actual:   $actual" >&2
    exit 1
  fi
}

install_binary() {
  local version="${1:-latest}"
  local url="${OKAL_DOWNLOAD_BASE_URL}/${version}/${OS}-${ARCH}/okal"
  tmp=$(mktemp -d); trap 'rm -rf "$tmp"' EXIT
  curl -fsSL --progress-bar "$url" -o "$tmp/okal"
  chmod +x "$tmp/okal"
  verify_sha256 "$tmp/okal" "$version"

  # Refuse to clobber an existing binary of different size unless --force.
  local target="$OKAL_INSTALL_DIR/okal"
  if [ -e "$target" ] && [ "${OKAL_FORCE:-0}" != "1" ]; then
    local existing_size new_size
    existing_size=$(stat -c%s "$target" 2>/dev/null || stat -f%z "$target")
    new_size=$(stat -c%s "$tmp/okal" 2>/dev/null || stat -f%z "$tmp/okal")
    if [ "$existing_size" != "$new_size" ]; then
      echo "Refusing to overwrite existing $target ($existing_size bytes) with new binary ($new_size bytes)." >&2
      echo "Pass --force or set OKAL_FORCE=1 to override." >&2
      exit 1
    fi
  fi

  if [ -w "$OKAL_INSTALL_DIR" ]; then mv "$tmp/okal" "$target"
  elif command -v sudo >/dev/null 2>&1 && sudo -n true 2>/dev/null; then sudo mv "$tmp/okal" "$target"
  else mkdir -p "$OKAL_FALLBACK_DIR"; mv "$tmp/okal" "$OKAL_FALLBACK_DIR/okal"; target="$OKAL_FALLBACK_DIR/okal"
  fi
  echo "Installed to: $target"
}

# Stub for --with-server / --stop — preserved as no-op so existing flows don't break.
run_with_server() {
  exit 1
}
run_stop() {
  echo "Use 'okal daemon stop' to stop the daemon."
  exit 1
}


main() {
  detect_platform
  case "${1:-}" in
    --with-server|--local) run_with_server ;;
    --stop)                run_stop ;;
    --force)               OKAL_FORCE=1; install_binary "${2:-latest}" ;;
    -h|--help)             echo "Usage: install.sh [--with-server|--stop|--force] [version]"; exit 0 ;;
    *)                     install_binary "${1:-latest}" ;;
  esac
  print_remote_server_token_hint
  printf "\n\033[1;32m✓ Okal CLI installed\033[0m\n"
  printf "  Next: \033[1;36mokal setup\033[0m  # Native mode, or run: okal setup --container\n"
}
main "$@"
