#!/bin/bash
# PingNitro для macOS — установка одной командой:
#     curl -fsSL https://pingnitro.com/mac.sh | bash
# Файл, скачанный curl (а не браузером), не получает пометки «скачано из интернета», поэтому macOS не блокирует запуск
# программы без платной подписи Apple. Взамен скрипт сам проверяет подлинность:
#   1) список версий https://pingnitro.com/download/latest.json — подпись RSA открытым ключом PingNitro (тот же ключ
#      вшит в программу и проверяет каждое обновление);
#   2) архив приложения — SHA-256 из подписанного списка;
# затем ставит PingNitro.app в «Программы» (нет прав — в ~/Applications) и запускает. Ничего, кроме PingNitro, не
# ставит и не меняет; пароль Mac не нужен. Исходник — tools/site/mac.sh (проект PingNitro), 07.10.2026.
# Язык сообщений (07.10.2026): первый язык системы (defaults read -g AppleLanguages), а если его нет — $LANG;
# ru uk be kk uz ky tg hy az — по-русски, остальное — по-английски. Каждое сообщение — пара «русский» «английский».
set -euo pipefail

main() {
  local URL SHA VER DEST   # T — глобальная: её убирает trap при выходе
  local EN=1 sl
  sl=$(defaults read -g AppleLanguages 2>/dev/null | sed -n '2p' | tr -d ' ",()' || true)   # первый язык, например ru-RU
  [ -n "$sl" ] || sl=${LC_ALL:-${LC_MESSAGES:-${LANG:-}}}
  sl=$(printf '%s' "$sl" | tr 'A-Z' 'a-z')
  case "${sl%%[-_.@]*}" in ru|uk|be|kk|uz|ky|tg|hy|az) EN=0 ;; esac
  L() { if [ "$EN" = 1 ]; then printf '%s' "$2"; else printf '%s' "$1"; fi; }   # L "по-русски" "in English"
  say() { printf '%s\n' "$*"; }
  fail() {
    say "PingNitro: $(L "$1" "$2")"
    say "$(L "Не вышло — напишите в поддержку t.me/pingnitrosupport или поставьте вручную: https://pingnitro.com/mac/" "Installation failed — message support at t.me/pingnitrosupport or install manually: https://pingnitro.com/en/mac/")"
    exit 1
  }

  [ "$(uname -s)" = Darwin ] || fail "это установщик для macOS" "this installer is for macOS only"
  [ "$(uname -m)" = arm64 ] || fail "нужен Mac на Apple Silicon (M1–M4); для Intel напишите в поддержку" "an Apple Silicon Mac (M1–M4) is required; for Intel, message support"
  local ver; ver=$(sw_vers -productVersion)
  [ "${ver%%.*}" -ge 13 ] || fail "нужна macOS 13 или новее (у вас $ver)" "macOS 13 or newer is required (you have $ver)"

  T=$(mktemp -d); trap 'rm -rf "$T"' EXIT
  say "PingNitro: $(L "проверяю последнюю версию…" "checking the latest version…")"
  curl -fsSL --retry 2 -m 30 https://pingnitro.com/download/latest.json -o "$T/latest.json" || fail "сайт не отвечает" "the website is not responding"

  # JSON читает JavaScript самой macOS (osascript) — без Python и сторонних программ
  js() { osascript -l JavaScript -e 'function run(a){ObjC.import("Foundation");var s=$.NSString.stringWithContentsOfFileEncodingError(a[0],$.NSUTF8StringEncoding,null).js;var o=JSON.parse(s);var v=o;a[1].split(".").forEach(function(k){v=(v==null)?null:v[k]});if(v==null)throw new Error(a[2]+a[1]);return String(v)}' "$1" "$2" "$(L "нет поля " "no field ")"; }
  js "$T/latest.json" payload > "$T/payload.b64" || fail "список версий не прочитался" "couldn't read the version list"
  js "$T/latest.json" sig > "$T/sig.b64" || fail "список версий не прочитался" "couldn't read the version list"
  base64 -D -i "$T/payload.b64" -o "$T/payload" && base64 -D -i "$T/sig.b64" -o "$T/sig" || fail "список версий повреждён" "the version list is damaged"
  cat > "$T/pub.pem" <<'KEY'
-----BEGIN PUBLIC KEY-----
MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAkfC2oCsco0H3VfKLnfC0
o5WJcp1jj77Bt4OqSMK/rVhChVZKpbxaiqGFC4sCccH6hyA7RLyBRwF6t1OWFMTk
+/9CDYl0oA11voBpFI/86JED/FyI+SOp3u/v21JLx3y5Oodv57L/Pljijp6P6c6L
1ZEBpnVzpbtFMPGKBQPglYYE6UHFVrlMKbJrh8Q4MzJaOzGPNEocehgsh+xjWtYk
ewCjLD9vpKHXiREfw2iE5wRvMZacEzRJZuQTOCsPrJ2gW+Wux949XMGrfw33fRZH
onnIdL5/vrlBQQLeiurf0hv7hdT9T6AYVH06JBtPSko8bu4Jx+qzUPEfcupOzrIM
ZNrJq9VdOw6DL3UnIYYtjX40T8MJO/cz857jg5hJC33QGPv/n6urWGFZVzjIh1uc
N8dVt5e2wWk5AAniStXQfp+1xJGmtiAT85PpJIwFyLyoR6ssKCvCzMr8J6lLwlK0
7HvXoCfaltt1R15niY8/2LmOqPQPN19LEp4KB06JMl5BAgMBAAE=
-----END PUBLIC KEY-----
KEY
  openssl dgst -sha256 -verify "$T/pub.pem" -signature "$T/sig" "$T/payload" >/dev/null 2>&1 \
    || fail "подпись списка версий не сошлась — ничего не ставлю" "the version list signature does not match — installing nothing"
  URL=$(js "$T/payload" mac.url) && SHA=$(js "$T/payload" mac.sha256) && VER=$(js "$T/payload" mac.version) \
    || fail "в списке версий нет программы для Mac" "the version list has no app for Mac"
  case "$URL" in https://pingnitro.com/download/PingNitro-mac-*.zip) ;; *) fail "неожиданный адрес архива: $URL" "unexpected archive address: $URL" ;; esac

  say "PingNitro $VER: $(L "скачиваю…" "downloading…")"
  curl -fSL --retry 2 -m 300 --progress-bar "$URL" -o "$T/app.zip" || fail "архив не скачался" "the archive did not download"
  [ "$(shasum -a 256 "$T/app.zip" | cut -d' ' -f1)" = "$SHA" ] || fail "контрольная сумма архива не сошлась — ничего не ставлю" "the archive checksum does not match — installing nothing"
  ditto -x -k "$T/app.zip" "$T/x" || fail "архив не распаковался" "the archive did not unpack"
  [ -d "$T/x/PingNitro.app" ] || fail "в архиве нет PingNitro.app" "there is no PingNitro.app in the archive"

  DEST=/Applications
  [ -w "$DEST" ] || { DEST="$HOME/Applications"; mkdir -p "$DEST"; }
  if pgrep -xq PingNitro; then   # работающая копия: закрыть (маршрут прервётся на несколько секунд)
    say "PingNitro: $(L "закрываю работающую копию…" "closing the running copy…")"
    osascript -e 'tell application id "com.pingnitro.app" to quit' >/dev/null 2>&1 || true
    for _ in 1 2 3 4 5 6 7 8 9 10; do pgrep -xq PingNitro || break; sleep 1; done
  fi
  rm -rf "$DEST/PingNitro.app.new"
  ditto "$T/x/PingNitro.app" "$DEST/PingNitro.app.new"
  rm -rf "$DEST/PingNitro.app"
  mv "$DEST/PingNitro.app.new" "$DEST/PingNitro.app"
  xattr -dr com.apple.quarantine "$DEST/PingNitro.app" 2>/dev/null || true
  open "$DEST/PingNitro.app"
  say "$(L "Готово: PingNitro $VER установлен в $DEST и запущен." "Done: PingNitro $VER is installed in $DEST and running.")"
  say "$(L "Дальше: в окне программы — «Войти через Telegram». В терминале прокси: HTTP 127.0.0.1, порт 1081." "Next: in the app window, click \"Sign in with Telegram\". In your terminal, set the proxy: HTTP 127.0.0.1, port 1081.")"
}

main "$@"
