#!/bin/sh
# oxidize installer — fast, local-first LLM inference in Rust
#
#   curl -fsSL https://zapdev.link/install.sh | sh
#
# Downloads a prebuilt `oxidize` binary for your platform and installs it to
# /usr/local/bin (or $OXIDIZE_INSTALL_DIR). Falls back to building from source
# with cargo when no prebuilt binary is published for your platform.
#
# Environment overrides:
#   OXIDIZE_INSTALL_DIR   install directory (default: /usr/local/bin)
#   OXIDIZE_VERSION       release tag to install (default: latest)

set -eu

REPO="Zapdev-labs/oxidize"
BIN="oxidize"
INSTALL_DIR="${OXIDIZE_INSTALL_DIR:-/usr/local/bin}"
VERSION="${OXIDIZE_VERSION:-latest}"

# ---- pretty output -----------------------------------------------------------
if [ -t 1 ] && [ -z "${NO_COLOR:-}" ]; then
  BOLD=$(printf '\033[1m'); DIM=$(printf '\033[2m'); RED=$(printf '\033[31m')
  GREEN=$(printf '\033[32m'); RESET=$(printf '\033[0m')
else
  BOLD=''; DIM=''; RED=''; GREEN=''; RESET=''
fi

info()  { printf '%s==>%s %s\n' "$BOLD" "$RESET" "$1"; }
ok()    { printf '%s  ok%s %s\n' "$GREEN" "$RESET" "$1"; }
warn()  { printf '%swarn%s %s\n' "$RED" "$RESET" "$1" >&2; }
die()   { printf '%serror%s %s\n' "$RED" "$RESET" "$1" >&2; exit 1; }

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

# ---- detect platform ---------------------------------------------------------
detect_platform() {
  os=$(uname -s)
  arch=$(uname -m)

  case "$os" in
    Linux)  OS="linux" ;;
    Darwin) OS="darwin" ;;
    *)      die "unsupported OS: $os (try building from source: https://github.com/$REPO)" ;;
  esac

  case "$arch" in
    x86_64|amd64)  ARCH="x86_64" ;;
    arm64|aarch64) ARCH="aarch64" ;;
    *)             die "unsupported architecture: $arch" ;;
  esac

  TARGET="${OS}-${ARCH}"
}

# ---- download helper ---------------------------------------------------------
download() {
  url="$1"; out="$2"
  if have curl; then
    curl -fsSL "$url" -o "$out"
  elif have wget; then
    wget -qO "$out" "$url"
  else
    die "need curl or wget to download"
  fi
}

resolve_version() {
  if [ "$VERSION" = "latest" ]; then
    api="https://api.github.com/repos/$REPO/releases/latest"
    if have curl; then
      VERSION=$(curl -fsSL "$api" 2>/dev/null | grep '"tag_name"' | head -n1 | cut -d'"' -f4 || true)
    elif have wget; then
      VERSION=$(wget -qO- "$api" 2>/dev/null | grep '"tag_name"' | head -n1 | cut -d'"' -f4 || true)
    fi
  fi
  [ -n "$VERSION" ] || return 1
}

# ---- install prebuilt binary -------------------------------------------------
install_prebuilt() {
  resolve_version || return 1
  asset="${BIN}-${TARGET}.tar.gz"
  url="https://github.com/$REPO/releases/download/$VERSION/$asset"

  tmp=$(mktemp -d 2>/dev/null || mktemp -d -t oxidize)
  trap 'rm -rf "$tmp"' EXIT

  info "downloading $BIN $VERSION ($TARGET)"
  download "$url" "$tmp/$asset" 2>/dev/null || return 1

  tar -xzf "$tmp/$asset" -C "$tmp" 2>/dev/null || return 1
  binpath=$(find "$tmp" -type f -name "$BIN" 2>/dev/null | head -n1)
  [ -n "$binpath" ] || return 1
  chmod +x "$binpath"

  place_binary "$binpath"
}

# ---- build from source -------------------------------------------------------
install_from_source() {
  info "no prebuilt binary found — building from source with cargo"
  have cargo || die "cargo not found. Install Rust from https://rustup.rs then re-run."

  info "installing $BIN via cargo (this can take a few minutes)"
  cargo install --git "https://github.com/$REPO" --bin "$BIN" --locked
  ok "installed via cargo to $(dirname "$(command -v "$BIN")")"
  POST_PATH_DIR="$(dirname "$(command -v "$BIN" 2>/dev/null || echo "$HOME/.cargo/bin/$BIN")")"
}

# ---- place binary into install dir -------------------------------------------
place_binary() {
  src="$1"
  if [ -w "$INSTALL_DIR" ] || mkdir -p "$INSTALL_DIR" 2>/dev/null && [ -w "$INSTALL_DIR" ]; then
    install -m 755 "$src" "$INSTALL_DIR/$BIN"
  else
    info "elevated permissions needed to write to $INSTALL_DIR"
    have sudo || die "cannot write to $INSTALL_DIR and sudo is unavailable. Set OXIDIZE_INSTALL_DIR to a writable path."
    sudo install -m 755 "$src" "$INSTALL_DIR/$BIN"
  fi
  POST_PATH_DIR="$INSTALL_DIR"
  ok "installed to $INSTALL_DIR/$BIN"
}

# ---- main --------------------------------------------------------------------
main() {
  printf '%s\n' "${BOLD}oxidize installer${RESET} ${DIM}— local-first LLM inference in Rust${RESET}"
  detect_platform
  info "platform: $TARGET"

  if ! install_prebuilt; then
    install_from_source
  fi

  # PATH hint
  case ":${PATH}:" in
    *":${POST_PATH_DIR}:"*) : ;;
    *) warn "$POST_PATH_DIR is not on your PATH — add it:"
       printf '       export PATH="%s:$PATH"\n' "$POST_PATH_DIR" ;;
  esac

  printf '\n%sDone.%s Get started:\n\n' "$GREEN" "$RESET"
  printf '    %soxidize run llama3.2%s     # download + serve an OpenAI-compatible API\n' "$BOLD" "$RESET"
  printf '    %soxidize --help%s\n\n' "$BOLD" "$RESET"
  printf '  Docs: https://github.com/%s\n' "$REPO"
}

main
