#!/usr/bin/env bash
# ============================================================================
#  Healand — Mac remote-build agent  (FOREGROUND daemon, có giám sát)
# ----------------------------------------------------------------------------
#  Mục đích: mở một đường để Claude (sandbox) SSH vào Mac này ký & build app
#  iOS, RỒI tự dọn sạch khi bạn Ctrl+C. Không launchd, không secret at rest,
#  mật khẩu chỉ sống trong RAM của tiến trình này.
#
#  Cách chạy (giữ Terminal MỞ suốt phiên build):
#     curl -fsSL https://healand-agent.6iang.dev/agent.sh | bash
#     ... | bash -s -- --uninstall   # gỡ tunnel đã tạo + pubkey khỏi authorized_keys
#     ... | bash -s -- --cleanup     # (sudo) diệt mọi launchd/keychain-cred persistent CŨ
#
#  Nhập mật khẩu macOS khi được hỏi (Enter = bỏ qua → chỉ mở tunnel, KHÔNG ký
#  được vì keychain khoá). Ctrl+C = trap dọn: kill tunnel/caffeinate, gỡ pubkey,
#  xoá socket, khoá keychain → mật khẩu bay theo RAM.
# ============================================================================
set -uo pipefail

# --- Pubkey của Claude (backup bền tại sandbox: .mac-agent/build_key) ---------
PUBKEY='ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBRbCUuczqiR8S5QjaaErUe0+TeeD3OWbiumgE00zdgl claude-healand-build-2'

TUNNEL_NAME='healand-mac'
TUNNEL_HOST='mac.6iang.com'
AGENT_DIR="$HOME/.neo-agent"
SOCK="$AGENT_DIR/pw.sock"
AUTHKEYS="$HOME/.ssh/authorized_keys"
CF_DIR="$HOME/.cloudflared"

log()  { printf '\033[36m[agent]\033[0m %s\n' "$*"; }
warn() { printf '\033[33m[agent] ⚠ %s\033[0m\n' "$*" >&2; }
die()  { printf '\033[31m[agent] ✗ %s\033[0m\n' "$*" >&2; exit 1; }

MODE=run
for a in "${@:-}"; do
  case "$a" in
    --uninstall) MODE=uninstall ;;
    --cleanup)   MODE=cleanup ;;
  esac
done

# ---------------------------------------------------------------------------
#  Gỡ pubkey khỏi authorized_keys (idempotent)
# ---------------------------------------------------------------------------
remove_key() {
  [ -f "$AUTHKEYS" ] || return 0
  grep -vF "$PUBKEY" "$AUTHKEYS" > "$AUTHKEYS.tmp" 2>/dev/null || true
  mv "$AUTHKEYS.tmp" "$AUTHKEYS" 2>/dev/null || true
  chmod 600 "$AUTHKEYS" 2>/dev/null || true
}

# ---------------------------------------------------------------------------
#  --uninstall : gỡ route/tunnel + pubkey (không cần sudo)
# ---------------------------------------------------------------------------
if [ "$MODE" = uninstall ]; then
  log "Gỡ tunnel '$TUNNEL_NAME' + pubkey…"
  command -v cloudflared >/dev/null 2>&1 && {
    cloudflared tunnel cleanup "$TUNNEL_NAME" >/dev/null 2>&1 || true
    cloudflared tunnel delete  "$TUNNEL_NAME" >/dev/null 2>&1 || true
  }
  remove_key
  rm -f "$SOCK"
  log "Xong. (DNS record $TUNNEL_HOST xoá thủ công ở Cloudflare nếu muốn.)"
  exit 0
fi

# ---------------------------------------------------------------------------
#  --cleanup : diệt các cơ chế persistent CŨ (launchd/keychain-cred) — cần sudo
# ---------------------------------------------------------------------------
if [ "$MODE" = cleanup ]; then
  log "Dọn mọi tàn dư persistent cũ (cần sudo)…"
  for lbl in com.neo.agent com.healand.agent com.healand.mac com.neo.tunnel; do
    sudo launchctl bootout "system/$lbl"          2>/dev/null || true
    launchctl bootout "gui/$(id -u)/$lbl"          2>/dev/null || true
    sudo rm -f "/Library/LaunchDaemons/$lbl.plist" 2>/dev/null || true
    rm -f "$HOME/Library/LaunchAgents/$lbl.plist"  2>/dev/null || true
  done
  security delete-generic-password -l 'neo-agent'  2>/dev/null || true
  remove_key
  rm -rf "$AGENT_DIR"
  log "Đã dọn sạch persistence cũ."
  exit 0
fi

# ===========================================================================
#  MODE = run  (foreground daemon)
# ===========================================================================
[ "$(uname)" = Darwin ] || die "Script này chỉ chạy trên macOS."
mkdir -p "$AGENT_DIR" "$HOME/.ssh" "$CF_DIR"
chmod 700 "$HOME/.ssh" 2>/dev/null || true

# --- 1. Dependencies: Homebrew + cloudflared/jq -----------------------------
if ! command -v brew >/dev/null 2>&1; then
  warn "Chưa có Homebrew. Cài: https://brew.sh (bỏ qua nếu cloudflared/jq đã có)."
fi
for pkg in cloudflared jq; do
  command -v "$pkg" >/dev/null 2>&1 || {
    log "Cài $pkg…"; brew install "$pkg" >/dev/null 2>&1 || warn "brew install $pkg thất bại — cài tay."
  }
done
command -v cloudflared >/dev/null 2>&1 || die "Cần cloudflared."
command -v jq          >/dev/null 2>&1 || die "Cần jq."

# --- 2. Bật Remote Login (SSH) ---------------------------------------------
if ! sudo systemsetup -getremotelogin 2>/dev/null | grep -qi On; then
  log "Bật Remote Login (SSH)…"
  sudo systemsetup -setremotelogin on 2>/dev/null \
    || warn "Không bật được bằng lệnh (macOS mới cần Full Disk Access). Bật tay: Settings → General → Sharing → Remote Login."
fi

# --- 3. Nạp pubkey của Claude ----------------------------------------------
touch "$AUTHKEYS"; chmod 600 "$AUTHKEYS"
grep -qF "$PUBKEY" "$AUTHKEYS" || { echo "$PUBKEY" >> "$AUTHKEYS"; log "Đã nạp pubkey Claude."; }

# --- 4. Chống ngủ (chỉ khi cắm nguồn) --------------------------------------
ON_AC=0
if pmset -g ps 2>/dev/null | grep -qi "AC Power"; then
  ON_AC=1
  sudo pmset -c sleep 0 2>/dev/null || warn "Không set được pmset sleep 0."
  log "Đang cắm nguồn → chống ngủ bật."
else
  warn "KHÔNG cắm nguồn → macOS sẽ ép ngủ và rớt tunnel. Cắm sạc + màn ngoài (clamshell)."
fi

# --- 5. Cloudflare Tunnel (tạo nếu chưa có, non-fatal khi đã tồn tại) --------
if [ ! -f "$CF_DIR/cert.pem" ]; then
  warn "Chưa login cloudflared. Mở trình duyệt để cấp quyền zone 6iang.com…"
  cloudflared tunnel login || die "cloudflared login thất bại."
fi
cloudflared tunnel create "$TUNNEL_NAME" 2>/dev/null \
  || log "Tunnel '$TUNNEL_NAME' đã tồn tại — dùng lại."
TID=$(cloudflared tunnel list -o json 2>/dev/null | jq -r ".[]|select(.name==\"$TUNNEL_NAME\")|.id")
[ -n "${TID:-}" ] || die "Không lấy được tunnel id."
cloudflared tunnel route dns "$TUNNEL_NAME" "$TUNNEL_HOST" 2>/dev/null \
  || log "DNS route $TUNNEL_HOST đã có — bỏ qua."

# Config ingress SSH (ghi mỗi lần cho chắc)
cat > "$CF_DIR/config-$TUNNEL_NAME.yml" <<YAML
tunnel: $TID
credentials-file: $CF_DIR/$TID.json
ingress:
  - hostname: $TUNNEL_HOST
    service: ssh://localhost:22
  - service: http_status:404
YAML

# --- 6. Đọc mật khẩu qua /dev/tty (stdin là pipe của curl) ------------------
MACPW=""
if [ -r /dev/tty ]; then
  printf '\033[36m[agent]\033[0m Mật khẩu macOS (Enter = chỉ mở tunnel, không ký được): '
  IFS= read -rs MACPW < /dev/tty || true
  echo
else
  warn "Không đọc được /dev/tty → chạy tunnel-only (không phục vụ mật khẩu)."
fi

# ---------------------------------------------------------------------------
#  Cleanup + trap  — Ctrl+C hoặc đóng terminal = dọn sạch
# ---------------------------------------------------------------------------
TUNNEL_PID=""; CAFF_PID=""; PW_PID=""
cleanup() {
  trap - INT TERM HUP EXIT
  echo; log "Đang dọn…"
  [ -n "$PW_PID" ]     && kill "$PW_PID"     2>/dev/null || true
  [ -n "$CAFF_PID" ]   && kill "$CAFF_PID"   2>/dev/null || true
  [ -n "$TUNNEL_PID" ] && kill "$TUNNEL_PID" 2>/dev/null || true
  rm -f "$SOCK"
  remove_key
  security lock-keychain "$HOME/Library/Keychains/login.keychain-db" 2>/dev/null || true
  MACPW=""
  log "Đã gỡ pubkey + tunnel + socket. Mật khẩu đã xoá khỏi RAM. Chào."
  exit 0
}
trap cleanup INT TERM HUP EXIT

# --- 7. caffeinate (giữ thức khi cắm nguồn) --------------------------------
if [ "$ON_AC" = 1 ]; then
  caffeinate -dimsu &        # d:display i:idle m:disk s:system u:user-active
  CAFF_PID=$!
fi

# --- 8. Server phục vụ mật khẩu qua unix socket (nếu có nhập pw) -------------
#  Claude phía SSH fetch pw để `security unlock-keychain` IN-SESSION rồi codesign
#  (unlock ở phiên GUI KHÔNG lan sang phiên SSH → phải serve qua socket).
if [ -n "$MACPW" ]; then
  (
    while :; do
      rm -f "$SOCK"                                   # BẮT BUỘC trước mỗi lần listen
      printf '%s' "$MACPW" | nc -lU "$SOCK" >/dev/null 2>&1 || true
      sleep 0.2
    done
  ) &
  PW_PID=$!
  chmod 600 "$SOCK" 2>/dev/null || true
  log "Đang phục vụ mật khẩu qua $SOCK (chỉ localhost, chỉ phiên này)."
else
  log "Không có mật khẩu → tunnel-only. Không ký/codesign được."
fi

# --- 9. Chạy tunnel ở FOREGROUND (block tới khi Ctrl+C) ---------------------
log "Mở tunnel → https://$TUNNEL_HOST (ssh://localhost:22). GIỮ terminal này MỞ."
log "Claude kết nối: ssh mac   (ProxyCommand cloudflared access ssh --hostname $TUNNEL_HOST)"
cloudflared tunnel --config "$CF_DIR/config-$TUNNEL_NAME.yml" run "$TUNNEL_NAME" &
TUNNEL_PID=$!
wait "$TUNNEL_PID"
