#!/bin/bash
# qcode installer — https://qlaud.ai/qcode
# Usage: curl -fsSL https://qlaud.ai/install/qcode | bash
#
# Supports macOS (arm64 + x86_64) and Linux (x86_64). Windows users:
#   irm https://qlaud.ai/install/qcode.ps1 | iex
set -euo pipefail

# Pretty status helpers (no-color fallback if stdout isn't a TTY).
if [ -t 1 ]; then
  BOLD='\033[1m'; DIM='\033[2m'; OK='\033[32m'; WARN='\033[33m'
  ERR='\033[31m'; RESET='\033[0m'
else
  BOLD=''; DIM=''; OK=''; WARN=''; ERR=''; RESET=''
fi
say()  { printf "%b%s%b\n" "$BOLD" "$1" "$RESET"; }
note() { printf "%b  %s%b\n" "$DIM" "$1" "$RESET"; }
ok()   { printf "%b✓%b %s\n" "$OK" "$RESET" "$1"; }
warn() { printf "%b!%b %s\n" "$WARN" "$RESET" "$1" >&2; }
err()  { printf "%b✗ qcode installer:%b %s\n" "$ERR" "$RESET" "$1" >&2; exit 1; }

# curl with a real progress bar when stderr is a TTY (-#), silent
# fallback for piped runs (-s) so logs don't fill with garbled
# carriage-return sequences. -fL fails fast on 4xx/5xx and follows
# redirects (the manifest endpoint 302s to GitHub).
download() {
  local url="$1" dst="$2"
  local progress
  if [ -t 2 ]; then progress="-#"; else progress="-s"; fi
  curl -fL $progress -o "$dst" "$url"
}

OS=$(uname -s)
ARCH=$(uname -m)

# Resolve the version we're about to install BEFORE the download
# so the user sees what they're getting. Falls back to "latest" if
# the version endpoint is unavailable (older server / network blip).
VERSION=$(curl -fsS "https://api.qlaud.ai/qcode/version" 2>/dev/null || echo "latest")

case "$OS" in

  # ─── macOS ──────────────────────────────────────────────────────
  Darwin)
    case "$ARCH" in
      arm64|aarch64) PLATFORM="mac-arm64"; PRETTY_ARCH="Apple Silicon" ;;
      x86_64)        PLATFORM="mac-x64";   PRETTY_ARCH="Intel"         ;;
      *) err "Unsupported macOS arch: $ARCH" ;;
    esac

    say "qcode installer"
    note "version:  $VERSION"
    note "platform: macOS $PRETTY_ARCH ($PLATFORM)"
    note "target:   /Applications/qcode.app"
    echo

    # Quit running app cleanly so the .app replace doesn't hit a busy file.
    if pgrep -x qcode >/dev/null 2>&1; then
      note "Quitting running qcode…"
      osascript -e 'tell app "qcode" to quit' 2>/dev/null || true
      sleep 1
    fi

    # Detach any stale /Volumes/qcode* mounts. macOS auto-suffixes when
    # a name is taken; if we leave them stacked the wrong copy can be
    # picked.
    for vol in /Volumes/qcode*; do
      if [ -d "$vol" ]; then
        note "Ejecting stale mount $vol"
        hdiutil detach "$vol" -quiet 2>/dev/null || true
      fi
    done

    DMG="/tmp/qcode-install-$$.dmg"
    say "Downloading…"
    if ! download "https://qlaud.ai/qcode/download/$PLATFORM" "$DMG"; then
      err "Download failed. The release for $PLATFORM may still be uploading — wait 1-2 minutes and retry, or grab the .dmg manually from https://github.com/qlaudAI/qcode/releases/latest"
    fi
    SIZE=$(du -h "$DMG" 2>/dev/null | awk '{print $1}')
    ok "Downloaded ($SIZE)"

    say "Mounting installer…"
    MOUNT=$(hdiutil attach "$DMG" -nobrowse 2>/dev/null | tail -1 | awk -F'\t' '{print $NF}' | sed 's/^ *//')
    if [ -z "$MOUNT" ] || [ ! -d "$MOUNT" ]; then
      rm -f "$DMG"
      err "DMG mount failed — the downloaded file may be corrupt. Re-run the installer."
    fi
    note "mount: $MOUNT"

    say "Installing to /Applications…"
    rm -rf /Applications/qcode.app
    cp -R "$MOUNT/qcode.app" /Applications/qcode.app
    hdiutil detach "$MOUNT" -quiet 2>/dev/null || true
    rm -f "$DMG"

    # Strip quarantine xattrs so macOS doesn't translocate the app on
    # first launch. The .app is Developer-ID signed + notarized, so
    # this is correct, not bypassing security.
    xattr -dr com.apple.quarantine /Applications/qcode.app 2>/dev/null || true

    INSTALLED=$(defaults read /Applications/qcode.app/Contents/Info.plist CFBundleShortVersionString 2>/dev/null || echo "?")
    echo
    ok "qcode $INSTALLED installed"
    note "launching…"
    open /Applications/qcode.app
    ;;

  # ─── Linux ──────────────────────────────────────────────────────
  Linux)
    case "$ARCH" in
      x86_64|amd64) ;;
      *) err "Unsupported Linux arch: $ARCH (x86_64 only for now)" ;;
    esac

    INSTALL_DIR="$HOME/.local/bin"
    APPIMAGE="$INSTALL_DIR/qcode"

    say "qcode installer"
    note "version:  $VERSION"
    note "platform: Linux x86_64"
    note "target:   $APPIMAGE"
    echo

    mkdir -p "$INSTALL_DIR"
    say "Downloading…"
    if ! download "https://qlaud.ai/qcode/download/linux" "$APPIMAGE"; then
      err "Download failed. Try again in 1-2 minutes, or grab the binary from https://github.com/qlaudAI/qcode/releases/latest"
    fi
    chmod +x "$APPIMAGE"
    SIZE=$(du -h "$APPIMAGE" 2>/dev/null | awk '{print $1}')
    echo
    ok "qcode $VERSION installed ($SIZE) → $APPIMAGE"

    # Help with PATH if it's not already set up. `.local/bin` is on
    # the modern Debian/Ubuntu/Fedora default $PATH so this usually
    # is a no-op, but older distros + minimal installs don't include
    # it.
    if ! echo ":$PATH:" | grep -q ":$INSTALL_DIR:"; then
      note "Note: $INSTALL_DIR isn't on your \$PATH. Add this to ~/.bashrc / ~/.zshrc:"
      printf "    export PATH=\"%s:\$PATH\"\n" "$INSTALL_DIR"
    fi
    note "Run: qcode"
    ;;

  *)
    err "Unsupported OS: $OS. Use Windows installer (irm https://qlaud.ai/install/qcode.ps1 | iex) or download from https://qlaud.ai/qcode"
    ;;
esac
