#!/usr/bin/env bash
# mobile-cc installer
#
# Source of truth: https://github.com/eyalev/mobile-cc/blob/main/install.sh
# (private repo at pre-alpha; the canonical-served copy is below)
# Live URL:        https://mobile-cc.dev/install.sh
# Pages fallback:  https://mobile-cc.pages.dev/install.sh
#
#   curl -fsSL https://mobile-cc.dev/install.sh | bash
#
# Knobs (env vars):
#   MOBILE_CC_BIND       — address:port to bind (default 127.0.0.1:7800)
#   MOBILE_CC_VERSION    — release tag to install (default: latest)
#   MOBILE_CC_PREFIX     — where to install the binary (default $HOME/.local/bin)
#   MOBILE_CC_BASE_URL   — install source base URL
#                          (default https://mobile-cc.dev, falls back to
#                           https://mobile-cc.pages.dev if the apex 404s)
#   MOBILE_CC_SKIP_UNIT  — set to 1 to skip the systemd user unit
#   MOBILE_CC_BIN_FILE   — install this local file instead of downloading
#                          (skips network entirely; for offline / test installs)
#
# Uninstall:
#   systemctl --user disable --now mobile-cc
#   rm -rf $HOME/.config/mobile-cc $HOME/.config/systemd/user/mobile-cc.service
#   rm -f  $HOME/.local/bin/mobile-cc

set -euo pipefail

BIND="${MOBILE_CC_BIND:-127.0.0.1:7800}"
PREFIX="${MOBILE_CC_PREFIX:-$HOME/.local/bin}"
UNIT_DIR="$HOME/.config/systemd/user"
BASE_URL="${MOBILE_CC_BASE_URL:-}"

mkdir -p "$PREFIX"

# ---------- preflight: warn loudly if binding non-loopback ----------
# mobile-cc itself refuses to bind non-loopback without --allow-public-bind +
# an env-var ack. The systemd unit below will pass both through when the user
# asks for it, but we want them to SEE the warning at install time, not
# later when they wonder why the daemon refused to start.
EXTRA_FLAGS=""
EXTRA_ENV=""
case "$BIND" in
  127.0.0.1:*|localhost:*|\[::1\]:*)
    : # safe default; nothing to do
    ;;
  *)
    cat >&2 <<WARN

  ⚠ WARNING: MOBILE_CC_BIND='$BIND' binds to a non-loopback address.
  ⚠ Anyone who can reach this port over the network will be able to drive
  ⚠ your tmux session. mobile-cc has NO built-in authentication.
  ⚠
  ⚠ Acceptable only if you have a reverse proxy with auth in front
  ⚠ (Caddy, oauth2-proxy, cloudflared with access policies), OR the
  ⚠ network is genuinely private (Tailscale tailnet, LAN-only).
  ⚠
  ⚠ Recommended instead: leave the default (127.0.0.1:7800) and tunnel
  ⚠ to your phone via Tailscale, 'ssh -L', or 'cloudflared'.

WARN
    EXTRA_FLAGS=" --allow-public-bind"
    EXTRA_ENV="Environment=MOBILE_CC_I_UNDERSTAND_THE_RISKS=1"
    ;;
esac

# ---------- preflight: tmux is a runtime prerequisite ----------
# mobile-cc attaches to your existing tmux server; it doesn't bundle or start
# one. If tmux is missing, the daemon still runs but /panes returns empty.
# Warn so users notice before opening the URL on their phone.
if ! command -v tmux >/dev/null 2>&1; then
  echo "mobile-cc: warning — tmux is not on PATH."
  echo "  Without tmux, mobile-cc starts but has nothing to attach to. Install it:"
  case "$(uname -s)" in
    Linux)
      if   command -v apt-get >/dev/null 2>&1; then echo "    sudo apt-get install -y tmux"
      elif command -v dnf >/dev/null 2>&1;     then echo "    sudo dnf install -y tmux"
      elif command -v pacman >/dev/null 2>&1;  then echo "    sudo pacman -S tmux"
      elif command -v apk >/dev/null 2>&1;     then echo "    sudo apk add tmux"
      else                                          echo "    (use your distro's package manager)"
      fi
      ;;
    Darwin) echo "    brew install tmux" ;;
    *)      echo "    (install tmux via your platform's package manager)" ;;
  esac
  echo "  Continuing — install mobile-cc anyway, then start a tmux session before opening the URL."
  echo
fi

# ---------- acquire binary ----------
if [ -n "${MOBILE_CC_BIN_FILE:-}" ]; then
  if [ ! -f "$MOBILE_CC_BIN_FILE" ]; then
    echo "mobile-cc: MOBILE_CC_BIN_FILE='$MOBILE_CC_BIN_FILE' does not exist" >&2
    exit 1
  fi
  echo "[1/3] installing local binary from $MOBILE_CC_BIN_FILE"
  install -m 0755 "$MOBILE_CC_BIN_FILE" "$PREFIX/mobile-cc"
else
  # resolve target
  OS=$(uname -s | tr '[:upper:]' '[:lower:]')
  ARCH=$(uname -m)
  case "$OS-$ARCH" in
    linux-x86_64)               TARGET="x86_64-unknown-linux-gnu" ;;
    linux-aarch64|linux-arm64)  TARGET="aarch64-unknown-linux-gnu" ;;
    darwin-x86_64)              TARGET="x86_64-apple-darwin" ;;
    darwin-arm64)               TARGET="aarch64-apple-darwin" ;;
    *) echo "mobile-cc: unsupported platform $OS-$ARCH" >&2; exit 1 ;;
  esac

  # resolve base URL with fallback (apex CNAME may not be wired yet)
  resolve_base_url() {
    if [ -n "$BASE_URL" ]; then echo "$BASE_URL"; return; fi
    # try the apex first, then pages.dev as fallback
    for url in "https://mobile-cc.dev" "https://mobile-cc.pages.dev"; do
      if curl -fsSL --max-time 4 -o /dev/null "$url/latest.txt"; then
        echo "$url"
        return
      fi
    done
    echo ""
  }
  BASE_URL=$(resolve_base_url)
  if [ -z "$BASE_URL" ]; then
    echo "mobile-cc: cannot reach either mobile-cc.dev or mobile-cc.pages.dev" >&2
    echo "           set MOBILE_CC_BASE_URL=<url> to an install mirror" >&2
    exit 1
  fi

  # resolve version
  if [ -z "${MOBILE_CC_VERSION:-}" ]; then
    MOBILE_CC_VERSION=$(curl -fsSL --max-time 5 "$BASE_URL/latest.txt" | tr -d '[:space:]')
  fi
  if [ -z "$MOBILE_CC_VERSION" ]; then
    echo "mobile-cc: could not resolve latest version from $BASE_URL/latest.txt" >&2
    exit 1
  fi

  ASSET="mobile-cc-${MOBILE_CC_VERSION}-${TARGET}.tar.gz"
  URL="${BASE_URL}/${MOBILE_CC_VERSION}/${ASSET}"

  echo "[1/3] downloading mobile-cc ${MOBILE_CC_VERSION} (${TARGET}) from ${BASE_URL}"
  TMP=$(mktemp -d); trap 'rm -rf "$TMP"' EXIT
  curl -fSL --max-time 60 "$URL" -o "$TMP/dl.tar.gz"

  # Verify the downloaded tarball against the published .sha256. Pages
  # publishes <asset>.sha256 alongside each tarball — fetching it on the
  # same TLS connection means an attacker controlling the network can't
  # serve a tampered binary + matching hash unless they also break TLS.
  echo "      verifying sha256..."
  if curl -fsSL --max-time 30 "${URL}.sha256" -o "$TMP/dl.tar.gz.sha256"; then
    expected=$(awk '{print $1}' "$TMP/dl.tar.gz.sha256")
    if   command -v sha256sum >/dev/null 2>&1; then
      actual=$(sha256sum "$TMP/dl.tar.gz" | awk '{print $1}')
    elif command -v shasum >/dev/null 2>&1; then
      actual=$(shasum -a 256 "$TMP/dl.tar.gz" | awk '{print $1}')
    else
      echo "mobile-cc: WARNING — neither sha256sum nor shasum found; skipping integrity check." >&2
      actual="$expected"  # skip the comparison below
    fi
    if [ "$expected" != "$actual" ]; then
      echo "" >&2
      echo "mobile-cc: SHA-256 mismatch on downloaded binary!" >&2
      echo "  expected: $expected" >&2
      echo "  actual:   $actual" >&2
      echo "  url:      $URL" >&2
      echo "" >&2
      echo "Refusing to install. This could be a corrupted download, or someone" >&2
      echo "tampering with the network path. Re-run; if it persists, file an" >&2
      echo "issue at https://github.com/eyalev/mobile-cc/issues ." >&2
      exit 1
    fi
  else
    echo "mobile-cc: WARNING — could not fetch .sha256 sibling; skipping integrity check." >&2
  fi

  tar -xzf "$TMP/dl.tar.gz" -C "$TMP"
  BIN_SRC=$(find "$TMP" -maxdepth 2 -type f -perm -u+x ! -name '*.tar.gz' | head -1)
  if [ -z "$BIN_SRC" ]; then
    echo "mobile-cc: tarball did not contain an executable (got: $(ls "$TMP"))" >&2
    exit 1
  fi
  install -m 0755 "$BIN_SRC" "$PREFIX/mobile-cc"
fi

# ---------- systemd user unit ----------
if [ "${MOBILE_CC_SKIP_UNIT:-0}" != "1" ] && command -v systemctl >/dev/null 2>&1; then
  echo "[2/3] writing systemd user unit"
  mkdir -p "$UNIT_DIR"
  cat > "$UNIT_DIR/mobile-cc.service" <<UNIT
[Unit]
Description=mobile-cc — drive Claude Code from a mobile browser
After=default.target

[Service]
Type=simple
${EXTRA_ENV}
ExecStart=$PREFIX/mobile-cc --bind $BIND --app-name "Mobile CC"${EXTRA_FLAGS}
Restart=always
RestartSec=2

[Install]
WantedBy=default.target
UNIT
  systemctl --user daemon-reload
  systemctl --user enable --now mobile-cc.service
  echo "      enabled + started (systemctl --user status mobile-cc)"
else
  echo "[2/3] systemd skipped; start manually with:"
  echo "      $PREFIX/mobile-cc --bind $BIND --app-name 'Mobile CC'"
fi

# ---------- done ----------
echo "[3/3] ready"
echo
echo "    mobile-cc is listening on http://${BIND}/"
echo
case "$BIND" in
  127.0.0.1:*|localhost:*)
    PORT="${BIND##*:}"
    echo "    bound to loopback. Reach it from your phone via one of:"
    echo "      • tailscale:  http://<this-machine>.<tailnet>.ts.net:${PORT}/"
    echo "      • ssh tunnel: ssh -L ${PORT}:${BIND} <this-host>"
    echo "      • cloudflared tunnel run"
    ;;
  *)
    echo "    bound publicly. Make sure the port is firewalled or behind Tailscale —"
    echo "    anyone who can reach it can drive your tmux."
    ;;
esac
echo
echo "    survive logout:    loginctl enable-linger \$USER"
echo "    follow logs:       journalctl --user -u mobile-cc -f"
