#!/bin/bash
# Автозапуск Dolphin Manager на macOS через launchd: стартует при входе, перезапускается при падении.
# macOS 15+ блокирует запуск файлов с атрибутом com.apple.provenance из защищённых папок
# (Desktop, Documents, Downloads, iCloud). Фикс: если скрипт запущен из такой папки — копируем
# рабочие файлы через `cp -R` (копирование снимает provenance) в ~/dolphin-manager/ и дальше
# прописываем launchd на безопасный путь.
set -e
cd "$(dirname "$0")"
SRC="$(pwd)"
LABEL="com.chig1r.dolphin-manager"
PLIST="$HOME/Library/LaunchAgents/$LABEL.plist"
TARGET="$HOME/dolphin-manager"

# python3: ищем ТОЛЬКО по конкретным путям готовых установок.
# НЕ используем `command -v python3` и НЕ пробуем /usr/bin/python3 — на macOS 15+ голый
# python3 это stub который триггерит системный попап «установить инструменты разработчика»
# (Xcode CLT качается 1-8 часов). Пользователь Kenny 2026-10-18 словил это и завис.
# Правильно: ищем Python.org installer, Homebrew. Если нет — чётко просим поставить Python.org pkg.
PY=""
for cand in \
  /Library/Frameworks/Python.framework/Versions/Current/bin/python3 \
  /Library/Frameworks/Python.framework/Versions/3.14/bin/python3 \
  /Library/Frameworks/Python.framework/Versions/3.13/bin/python3 \
  /Library/Frameworks/Python.framework/Versions/3.12/bin/python3 \
  /Library/Frameworks/Python.framework/Versions/3.11/bin/python3 \
  /opt/homebrew/bin/python3 \
  /usr/local/bin/python3
do
  if [ -x "$cand" ]; then
    # дополнительная проверка — реально запускается (не stub) и это >= 3.9
    if "$cand" -c 'import sys; sys.exit(0 if sys.version_info >= (3,9) else 1)' 2>/dev/null; then
      PY="$cand"; break
    fi
  fi
done
if [ -z "$PY" ]; then
  echo ""
  echo "✗ Python 3.9+ не найден."
  echo ""
  echo "Что сделать (это быстро, 2 минуты):"
  echo "  1) ЗАКРОЙ попап «Установить инструменты командной строки» если он всплыл (нажми Отменить)."
  echo "     Эти инструменты качаются 1-8 часов и тебе НЕ НУЖНЫ."
  echo "  2) Открой в браузере:  https://www.python.org/downloads/macos/"
  echo "  3) Жми большую кнопку «Download Python 3.x.x» → качается .pkg файл (~50 МБ)."
  echo "  4) Двойной клик по .pkg → Продолжить → Принять → Установить (попросит пароль Mac)."
  echo "  5) Через минуту повтори ту же команду с сайта (из Terminal, ⌘+V, Enter)."
  echo ""
  exit 1
fi
echo "→ использую Python: $PY"

# определяем «защищённую» папку по признакам: Desktop, Documents, Downloads, iCloud, /Volumes, /tmp
needs_migration=0
case "$SRC" in
  "$HOME/Desktop"/*|"$HOME/Documents"/*|"$HOME/Downloads"/*|"$HOME/Library/Mobile Documents"/*|/Volumes/*|/tmp/*|/private/tmp/*)
    needs_migration=1 ;;
esac

# com.apple.provenance на app.py означает что файл приехал через карантин (Safari/AirDrop/скачивание)
# и launchd не сможет его запускать (posix_spawn → EPERM). Копирование через `cp -R` снимает атрибут.
has_provenance=0
if [ -f "$SRC/app.py" ] && xattr "$SRC/app.py" 2>/dev/null | grep -q com.apple.provenance; then
  has_provenance=1
fi

if [ "$needs_migration" = "1" ] || [ "$has_provenance" = "1" ]; then
  echo "→ исходная папка $SRC в защищённой зоне (или помечена provenance)."
  echo "→ копирую рабочие файлы в $TARGET/ (чистое место без TCC-ограничений)…"
  mkdir -p "$TARGET"
  # cp -R вместо rsync чтобы гарантированно снимать расширенные атрибуты
  for item in app.py dm requirements.txt start.command restart.command keepawake.command \
              start.bat install_autostart.bat uninstall_autostart.command web README.md; do
    if [ -e "$SRC/$item" ]; then
      rm -rf "$TARGET/$item" 2>/dev/null || true
      cp -R "$SRC/$item" "$TARGET/" 2>/dev/null || true
    fi
  done
  # config.json и состояние: не затираем если уже есть в целевой
  for item in config.json board.json events.json states.json; do
    if [ -f "$SRC/$item" ] && [ ! -f "$TARGET/$item" ]; then
      cp "$SRC/$item" "$TARGET/" 2>/dev/null || true
    fi
  done
  # на всякий случай пробуем снять provenance с копий (может не сработать на macOS 15 — но cp уже чистит)
  find "$TARGET" -maxdepth 3 \( -name "*.py" -o -name "*.command" -o -name "*.sh" \) -exec xattr -d com.apple.provenance {} \; 2>/dev/null || true
  DIR="$TARGET"
  echo "→ рабочая папка launchd: $DIR"
else
  DIR="$SRC"
fi

mkdir -p "$HOME/Library/LaunchAgents" "$DIR/logs"

# зависимости — молча, с таймаутом (чтобы не висеть если нет сети)
"$PY" -m pip install --user -q -r "$DIR/requirements.txt" >/dev/null 2>&1 || true

cat > "$PLIST" <<PLIST
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0"><dict>
  <key>Label</key><string>$LABEL</string>
  <key>ProgramArguments</key><array>
    <string>$PY</string><string>$DIR/app.py</string><string>--no-browser</string>
  </array>
  <key>WorkingDirectory</key><string>$DIR</string>
  <key>EnvironmentVariables</key><dict>
    <key>PATH</key><string>/usr/local/bin:/opt/homebrew/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>
    <key>LANG</key><string>en_US.UTF-8</string>
    <key>HOME</key><string>$HOME</string>
  </dict>
  <key>RunAtLoad</key><true/>
  <key>KeepAlive</key><dict><key>SuccessfulExit</key><false/></dict>
  <key>ThrottleInterval</key><integer>10</integer>
  <key>StandardOutPath</key><string>$DIR/logs/manager.log</string>
  <key>StandardErrorPath</key><string>$DIR/logs/manager.err.log</string>
</dict></plist>
PLIST

# снимаем старую регистрацию (игнор если не было)
launchctl bootout gui/$(id -u)/$LABEL 2>/dev/null || true
launchctl unload "$PLIST" 2>/dev/null || true
# освобождаем 8765 если занят вручную запущенной копией
OLD="$(lsof -ti tcp:8765 -sTCP:LISTEN 2>/dev/null || true)"
if [ -n "$OLD" ]; then
  echo "→ останавливаю запущенную копию на 8765 (pid $OLD)"
  kill $OLD 2>/dev/null || true
  sleep 1
fi
# bootstrap — современный путь (на macOS 15+ он надёжнее load)
launchctl bootstrap gui/$(id -u) "$PLIST" 2>&1 || launchctl load -w "$PLIST"
launchctl kickstart -k gui/$(id -u)/$LABEL 2>/dev/null || true

sleep 3
if curl -s -m 3 http://127.0.0.1:8765/api/ping | grep -q dolphin-manager; then
  V=$(curl -s -m 2 http://127.0.0.1:8765/api/ping | python3 -c 'import json,sys;print(json.load(sys.stdin).get("version","?"))' 2>/dev/null || echo "?")
  echo ""
  echo "✓ Dolphin Manager v$V запущен через launchd:"
  echo "  папка:  $DIR"
  echo "  логи:   $DIR/logs/manager.log"
  echo "  сайт:   http://127.0.0.1:8765"
  echo ""
  echo "Проверка автозапуска после перезагрузки — не требуется, launchd подхватит сам."
  echo "Снять автозапуск: bash $DIR/uninstall_autostart.command"
else
  echo ""
  echo "✗ локалка не ответила на http://127.0.0.1:8765/api/ping"
  echo "  смотри ошибки в: $DIR/logs/manager.err.log"
  echo "  или в system log: log show --predicate 'process == \"launchd\" AND composedMessage CONTAINS \"dolphin-manager\"' --last 2m"
  exit 1
fi
