#!/usr/bin/env bash
# sudoterm installer — Phase 1
# Hosted at https://sudoterm.com/install (served by apps/marketing/app/install/route.ts).
# Spec §10.1.
#
# Usage:
#   curl -fsSL https://sudoterm.com/install | bash
#   curl -fsSL https://sudoterm.com/install | bash -s -- --subdomain my-vps --no-interactive
#
# Flags:
#   --subdomain <name>       Preferred subdomain (skips prompt)
#   --no-interactive         Don't prompt; fail if required info missing
#   --dry-run                Print what would happen, don't change anything
#   --version <tag>          Pin a specific release tag (default: latest)
#   --registry <url>         Override api.sudoterm.com (dev)
#   --skip-cloudflared       Don't install cloudflared (assumes preinstalled)
#   --skip-systemd           Don't write a systemd unit (run daemon manually)
#
# Env:
#   SUDOTERM_INSTALL_DIR     Override /opt/sudoterm (default)
#   SUDOTERM_BIN_DIR         Override /usr/local/bin (default)

set -euo pipefail

# ─── colors ────────────────────────────────────────────────────────────────
if [ -t 1 ] && [ -z "${NO_COLOR:-}" ]; then
  C_BOLD=$'\e[1m'; C_DIM=$'\e[2m'; C_RED=$'\e[31m'; C_GREEN=$'\e[32m'
  C_YELLOW=$'\e[33m'; C_CYAN=$'\e[36m'; C_RESET=$'\e[0m'
else
  C_BOLD=''; C_DIM=''; C_RED=''; C_GREEN=''; C_YELLOW=''; C_CYAN=''; C_RESET=''
fi

step()  { printf '%s▸%s %s\n' "$C_CYAN" "$C_RESET" "$*"; }
ok()    { printf '%s✓%s %s\n' "$C_GREEN" "$C_RESET" "$*"; }
warn()  { printf '%s!%s %s\n' "$C_YELLOW" "$C_RESET" "$*"; }
die()   { printf '%s✗%s %s\n' "$C_RED" "$C_RESET" "$*" >&2; exit 1; }

# ─── flags ─────────────────────────────────────────────────────────────────
FLAG_SUBDOMAIN=""
FLAG_NO_INTERACTIVE=0
FLAG_DRY_RUN=0
FLAG_VERSION="latest"
FLAG_REGISTRY="${SUDOTERM_REGISTRY_BASE:-https://api.sudoterm.com}"
FLAG_SKIP_CLOUDFLARED=0
FLAG_SKIP_SYSTEMD=0

while [ $# -gt 0 ]; do
  case "$1" in
    --subdomain) FLAG_SUBDOMAIN="$2"; shift 2 ;;
    --no-interactive) FLAG_NO_INTERACTIVE=1; shift ;;
    --dry-run) FLAG_DRY_RUN=1; shift ;;
    --version) FLAG_VERSION="$2"; shift 2 ;;
    --registry) FLAG_REGISTRY="$2"; shift 2 ;;
    --skip-cloudflared) FLAG_SKIP_CLOUDFLARED=1; shift ;;
    --skip-systemd) FLAG_SKIP_SYSTEMD=1; shift ;;
    *) die "unknown flag $1" ;;
  esac
done

INSTALL_DIR="${SUDOTERM_INSTALL_DIR:-/opt/sudoterm}"
BIN_DIR="${SUDOTERM_BIN_DIR:-/usr/local/bin}"
GITHUB_REPO="${SUDOTERM_REPO:-sudoterm/sudoterm}"

run() {
  if [ "$FLAG_DRY_RUN" = 1 ]; then printf '%s$ %s%s\n' "$C_DIM" "$*" "$C_RESET"; return 0; fi
  "$@"
}

# ─── 1. OS detect ──────────────────────────────────────────────────────────
step "[1/14] detecting OS"
OS="$(uname -s)"
[ "$OS" = "Linux" ] || die "Phase 1 supports Linux only (got $OS). macOS/Windows are on the roadmap."
ARCH="$(uname -m)"
case "$ARCH" in
  x86_64|amd64) ARCH_TAG="amd64" ;;
  aarch64|arm64) ARCH_TAG="arm64" ;;
  *) die "unsupported arch: $ARCH" ;;
esac
ok "Linux $ARCH ($ARCH_TAG)"

# ─── 2. prerequisites ──────────────────────────────────────────────────────
step "[2/14] checking prerequisites"
need_install=()
for bin in tmux curl tar; do
  command -v "$bin" >/dev/null 2>&1 || need_install+=("$bin")
done

if [ ${#need_install[@]} -gt 0 ]; then
  warn "missing: ${need_install[*]}"
  if command -v apt-get >/dev/null 2>&1; then
    run sudo apt-get update -y
    run sudo apt-get install -y "${need_install[@]}"
  elif command -v dnf >/dev/null 2>&1; then
    run sudo dnf install -y "${need_install[@]}"
  elif command -v yum >/dev/null 2>&1; then
    run sudo yum install -y "${need_install[@]}"
  elif command -v apk >/dev/null 2>&1; then
    run sudo apk add --no-cache "${need_install[@]}"
  else
    die "no supported package manager (apt/dnf/yum/apk) — install ${need_install[*]} and re-run"
  fi
fi
ok "tmux / curl / tar present"

if ! command -v node >/dev/null 2>&1 || ! node -e 'process.version.split(".")[0].slice(1)>=22||process.exit(1)'; then
  warn "Node.js ≥22 not found"
  step "      installing Node.js 22 LTS via NodeSource"
  run bash -c 'curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -'
  run sudo apt-get install -y nodejs
fi
ok "node $(node -v 2>/dev/null || echo missing)"

# ─── 3. download release ───────────────────────────────────────────────────
step "[3/14] downloading sudoterm $FLAG_VERSION ($ARCH_TAG)"
if [ "$FLAG_VERSION" = "latest" ]; then
  RELEASE_URL="https://github.com/$GITHUB_REPO/releases/latest/download"
else
  RELEASE_URL="https://github.com/$GITHUB_REPO/releases/download/$FLAG_VERSION"
fi
TARBALL_URL="$RELEASE_URL/sudoterm-linux-$ARCH_TAG.tar.gz"
TMP_TAR="$(mktemp -t sudoterm.XXXXXX.tar.gz)"
trap 'rm -f "$TMP_TAR"' EXIT

if [ "$FLAG_DRY_RUN" = 1 ]; then
  warn "dry-run: would download $TARBALL_URL"
else
  if ! curl -fsSL --connect-timeout 10 "$TARBALL_URL" -o "$TMP_TAR"; then
    die "release tarball not found at $TARBALL_URL — is FLAG_VERSION right?"
  fi
fi
ok "downloaded"

# ─── 4. extract to /opt/sudoterm ───────────────────────────────────────────
step "[4/14] extracting to $INSTALL_DIR"
run sudo mkdir -p "$INSTALL_DIR"
run sudo tar -xzf "$TMP_TAR" -C "$INSTALL_DIR" --strip-components=1
ok "extracted"

# ─── 5. symlink ────────────────────────────────────────────────────────────
step "[5/14] linking $BIN_DIR/sudoterm"
run sudo ln -sf "$INSTALL_DIR/bin/sudoterm" "$BIN_DIR/sudoterm"
ok "symlinked"

# ─── 6. cloudflared ────────────────────────────────────────────────────────
step "[6/14] installing cloudflared"
if [ "$FLAG_SKIP_CLOUDFLARED" = 1 ]; then
  warn "skipped (--skip-cloudflared)"
elif command -v cloudflared >/dev/null 2>&1; then
  ok "already installed at $(command -v cloudflared)"
else
  CF_URL="https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-$ARCH_TAG"
  run sudo curl -fsSL "$CF_URL" -o "$BIN_DIR/cloudflared"
  run sudo chmod +x "$BIN_DIR/cloudflared"
  ok "installed cloudflared"
fi

# ─── 7. sudoterm user ──────────────────────────────────────────────────────
step "[7/14] determining service user"
if [ "$(id -u)" = 0 ]; then
  SUDOTERM_USER="${SUDO_USER:-root}"
else
  SUDOTERM_USER="$USER"
fi
ok "service user: $SUDOTERM_USER"

# ─── 8. install token ──────────────────────────────────────────────────────
step "[8/14] generating install token"
INSTALL_TOKEN="$(head -c 32 /dev/urandom | xxd -p -c 64)"
ok "32-byte token generated"

# ─── 9. interactive setup ──────────────────────────────────────────────────
step "[9/14] interactive setup"
PREFERRED_SUBDOMAIN="$FLAG_SUBDOMAIN"
if [ -z "$PREFERRED_SUBDOMAIN" ]; then
  DEFAULT_SUB="$(hostname -s 2>/dev/null | tr '[:upper:]' '[:lower:]' | tr -c 'a-z0-9' '-' | sed 's/-*$//' | head -c 30)"
  [ -z "$DEFAULT_SUB" ] && DEFAULT_SUB="my-vps"
  if [ "$FLAG_NO_INTERACTIVE" = 1 ]; then
    PREFERRED_SUBDOMAIN="$DEFAULT_SUB"
    warn "using default subdomain: $DEFAULT_SUB"
  else
    read -r -p "Preferred subdomain (default: $DEFAULT_SUB): " PREFERRED_SUBDOMAIN
    PREFERRED_SUBDOMAIN="${PREFERRED_SUBDOMAIN:-$DEFAULT_SUB}"
  fi
fi
ok "subdomain: $PREFERRED_SUBDOMAIN"

# ─── 10. register subdomain ────────────────────────────────────────────────
step "[10/14] registering with $FLAG_REGISTRY"
REG_PAYLOAD=$(printf '{"installToken":"%s","preferredSubdomain":"%s","hostname":"%s"}' \
  "$INSTALL_TOKEN" "$PREFERRED_SUBDOMAIN" "$(hostname)")
if [ "$FLAG_DRY_RUN" = 1 ]; then
  warn "dry-run: would POST to $FLAG_REGISTRY/api/register"
  TUNNEL_TOKEN="dry-run-token"
  REG_SUBDOMAIN="$PREFERRED_SUBDOMAIN"
  REG_FULLDOMAIN="$PREFERRED_SUBDOMAIN.sudoterm.com"
  REG_TUNNEL_ID="dry-run-tunnel-id"
else
  REG_RES="$(curl -fsS -X POST -H 'Content-Type: application/json' -d "$REG_PAYLOAD" \
    "$FLAG_REGISTRY/api/register")" || die "subdomain registration failed"
  # Parse JSON without jq dep — fall back to grep/sed
  if command -v jq >/dev/null 2>&1; then
    REG_SUBDOMAIN="$(printf '%s' "$REG_RES" | jq -r '.data.subdomain')"
    REG_FULLDOMAIN="$(printf '%s' "$REG_RES" | jq -r '.data.fullDomain')"
    REG_TUNNEL_ID="$(printf '%s' "$REG_RES" | jq -r '.data.tunnelId')"
    TUNNEL_TOKEN="$(printf '%s' "$REG_RES" | jq -r '.data.tunnelToken')"
  else
    REG_SUBDOMAIN="$(printf '%s' "$REG_RES" | sed -n 's/.*"subdomain":"\([^"]*\)".*/\1/p')"
    REG_FULLDOMAIN="$(printf '%s' "$REG_RES" | sed -n 's/.*"fullDomain":"\([^"]*\)".*/\1/p')"
    REG_TUNNEL_ID="$(printf '%s' "$REG_RES" | sed -n 's/.*"tunnelId":"\([^"]*\)".*/\1/p')"
    TUNNEL_TOKEN="$(printf '%s' "$REG_RES" | sed -n 's/.*"tunnelToken":"\([^"]*\)".*/\1/p')"
  fi
  [ -n "$TUNNEL_TOKEN" ] || die "registry response missing tunnelToken: $REG_RES"
fi
ok "registered $REG_FULLDOMAIN"

# ─── 11. write tunnel.json ─────────────────────────────────────────────────
step "[11/14] writing ~/.sudoterm/tunnel.json"
USER_HOME="$(eval echo "~$SUDOTERM_USER")"
SUDOTERM_USER_DIR="$USER_HOME/.sudoterm"
run sudo -u "$SUDOTERM_USER" mkdir -p "$SUDOTERM_USER_DIR"
run sudo -u "$SUDOTERM_USER" chmod 700 "$SUDOTERM_USER_DIR"
TUNNEL_JSON=$(cat <<EOF
{
  "subdomain": "$REG_SUBDOMAIN",
  "fullDomain": "$REG_FULLDOMAIN",
  "tunnelId": "$REG_TUNNEL_ID",
  "tunnelToken": "$TUNNEL_TOKEN",
  "registeredAt": $(date +%s)000
}
EOF
)
if [ "$FLAG_DRY_RUN" = 1 ]; then
  warn "dry-run: would write tunnel.json"
else
  printf '%s\n' "$TUNNEL_JSON" | sudo -u "$SUDOTERM_USER" tee "$SUDOTERM_USER_DIR/tunnel.json" >/dev/null
  run sudo -u "$SUDOTERM_USER" chmod 600 "$SUDOTERM_USER_DIR/tunnel.json"
fi
ok "tunnel.json written"

# ─── 12. systemd unit ──────────────────────────────────────────────────────
step "[12/14] installing systemd unit"
if [ "$FLAG_SKIP_SYSTEMD" = 1 ]; then
  warn "skipped (--skip-systemd)"
elif ! command -v systemctl >/dev/null 2>&1; then
  warn "systemctl not available — skipping unit install"
else
  UNIT_SRC="$INSTALL_DIR/assets/sudoterm.service"
  UNIT_DST="/etc/systemd/system/sudoterm.service"
  if [ ! -f "$UNIT_SRC" ]; then
    die "missing $UNIT_SRC — tarball is malformed"
  fi
  TMP_UNIT="$(mktemp)"
  sed "s|\${SUDOTERM_USER}|$SUDOTERM_USER|g" "$UNIT_SRC" > "$TMP_UNIT"
  run sudo install -m 644 "$TMP_UNIT" "$UNIT_DST"
  rm -f "$TMP_UNIT"
  run sudo systemctl daemon-reload
  run sudo systemctl enable sudoterm
  ok "unit installed + enabled"
fi

# ─── 13. start daemon ──────────────────────────────────────────────────────
step "[13/14] starting sudoterm.service"
if [ "$FLAG_SKIP_SYSTEMD" = 1 ] || ! command -v systemctl >/dev/null 2>&1; then
  warn "skipped — start with: sudo systemctl start sudoterm"
else
  run sudo systemctl start sudoterm
  sleep 2
  if systemctl is-active --quiet sudoterm; then
    ok "sudoterm.service active"
  else
    warn "service did not become active; check 'journalctl -u sudoterm'"
  fi
fi

# ─── 14. success banner ────────────────────────────────────────────────────
step "[14/14] done"
printf '\n%ssudoterm is installed.%s\n\n' "$C_BOLD" "$C_RESET"
printf '  Public URL: %shttps://%s%s\n' "$C_CYAN" "$REG_FULLDOMAIN" "$C_RESET"
printf '  Logs:       sudoterm logs\n'
printf '  Status:     sudoterm status\n'
printf '  Doctor:     sudoterm doctor\n'
printf '\nVisit your URL to finish setup (password + AI key).\n'
