#!/bin/sh
# ============================================================
#  GEODEMA VPN — установщик для OpenWrt (SSClash + mihomo)
#  Одна команда: ставит, спрашивает подписку, настраивает, запускает.
#  Использование: sh geodema.sh [САБ-ССЫЛКА]   (без аргумента — спросит)
# ============================================================
MIRROR="http://files.geodema.network"
MIRROR_IP="91.203.36.85"
SUB_HOSTS="account.geodema.org sub.geodema.org sub.rakeed.net"   # принимаем ТОЛЬКО наши
SSCLASH_VER="4.5.2-r1"

# --- ЧИСТО остановить прошлый clash (грязный killall ломает DNS → урезанный набор нод) ---
[ -x /etc/init.d/clash ] && /etc/init.d/clash stop 2>/dev/null
/etc/init.d/firewall restart >/dev/null 2>&1; sleep 2

# --- цвета ---
if [ -t 1 ] && [ "${TERM:-dumb}" != dumb ]; then
  R=$(printf '\033[0;31m'); G=$(printf '\033[0;32m'); Y=$(printf '\033[1;33m')
  C=$(printf '\033[0;36m'); B=$(printf '\033[1m'); N=$(printf '\033[0m')
else R=; G=; Y=; C=; B=; N=; fi
log(){ printf "%s  [+]%s %s\n" "$G" "$N" "$*"; }
info(){ printf "%s  [i]%s %s\n" "$C" "$N" "$*"; }
warn(){ printf "%s  [!]%s %s\n" "$Y" "$N" "$*"; }
die(){ printf "%s  [x] %s%s\n" "$R" "$*" "$N" >&2; exit 1; }

printf "%s%s\n" "$C$B" "  ╔══════════════════════════════════════╗"
printf "%s\n"   "  ║          GEODEMA VPN — установка      ║"
printf "%s%s\n" "  ╚══════════════════════════════════════╝" "$N"

# надёжная загрузка: ретраи + IPv4 + DNS-обход на IP зеркала
fetch(){ # $1=url $2=out
  curl -fL -4 --retry 3 --retry-delay 2 --connect-timeout 15 --max-time 200 "$1" -o "$2" 2>/tmp/gdl.err && [ -s "$2" ] && return 0
  curl -fL -4 --retry 3 --connect-timeout 15 --max-time 200 --resolve files.geodema.network:80:"$MIRROR_IP" "$1" -o "$2" 2>>/tmp/gdl.err && [ -s "$2" ] && return 0
  return 1
}

# ── [1/6] система ──
if command -v apk >/dev/null 2>&1 && [ -d /etc/apk ]; then PKG=apk; else PKG=opkg; fi
. /etc/openwrt_release 2>/dev/null
log "[1/6] Система: ${DISTRIB_DESCRIPTION:-OpenWrt} ($PKG)"

# curl
command -v curl >/dev/null 2>&1 || { warn "ставлю curl..."; if [ "$PKG" = apk ]; then apk update >/dev/null 2>&1; apk add curl >/dev/null 2>&1; else opkg update >/dev/null 2>&1; opkg install curl >/dev/null 2>&1; fi; }
command -v curl >/dev/null 2>&1 || die "не удалось поставить curl"

# ── [2/6] конфликты ──
info "[2/6] Поиск конфликтов..."
CONF=
for s in v2raya zapret https-dns-proxy nikki openclash passwall passwall2 shadowsocks-libev; do
  [ -x /etc/init.d/$s ] && CONF="$CONF $s"
done
if [ -n "$CONF" ]; then
  warn "Найдены другие VPN/DNS-сервисы:$CONF"
  warn "Они конфликтуют с Geodema VPN (дерутся за трафик и DNS — из-за этого «инет падает / сайты не грузят»)."
  printf "%s  Отключить их? [Y/n]: %s" "$B" "$N"; read ANS </dev/tty 2>/dev/null || ANS=Y
  case "$ANS" in [Nn]*) warn "оставлены — возможны конфликты";;
    *) for s in $CONF; do /etc/init.d/$s stop 2>/dev/null; /etc/init.d/$s disable 2>/dev/null; log "отключён: $s"; done;; esac
else log "[2/6] конфликтов нет"; fi

# ── [3/6] установка SSClash + ядра ──
info "[3/6] Установка SSClash + ядра mihomo..."
if [ "$PKG" = apk ]; then apk update >/dev/null 2>&1; apk add kmod-tun kmod-nft-tproxy coreutils-base64 >/dev/null 2>&1
else opkg update >/dev/null 2>&1; opkg install kmod-tun kmod-nft-tproxy coreutils-base64 >/dev/null 2>&1; fi
# luci-app-ssclash
if [ "$PKG" = apk ]; then
  fetch "$MIRROR/ssclash/luci-app-ssclash-$SSCLASH_VER.apk" /tmp/ssc.apk || die "загрузка пакета: $(tail -1 /tmp/gdl.err)"
  apk add --allow-untrusted /tmp/ssc.apk >/dev/null 2>&1 || die "установка пакета"
else
  fetch "$MIRROR/ssclash/luci-app-ssclash_${SSCLASH_VER}_all.ipk" /tmp/ssc.ipk || die "загрузка пакета: $(tail -1 /tmp/gdl.err)"
  (cd /tmp && opkg install ssc.ipk) >/dev/null 2>&1 || die "установка пакета"
fi
# ядро mihomo
ARCH=$(uname -m); case "$ARCH" in aarch64|arm64) CORE=arm64;; armv7l|armv7) CORE=armv7;; x86_64|amd64) CORE=amd64-compatible;; mips) CORE=mipsle-softfloat;; i?86) CORE=386;; *) CORE=amd64-compatible;; esac
fetch "$MIRROR/mihomo/mihomo-linux-$CORE.gz" /tmp/mihomo.gz || die "загрузка ядра"
gzip -dc /tmp/mihomo.gz > /opt/clash/bin/clash 2>/dev/null && chmod +x /opt/clash/bin/clash
log "[3/6] установлено"

# ── [4/6] подписка ──
SUB="$1"
if [ -z "$SUB" ]; then
  echo
  printf "%s  ┌─────────────────────────────────────────────┐%s\n" "$C$B" "$N"
  printf "%s  │  Вставьте вашу ссылку-подписку Geodema        │%s\n" "$C$B" "$N"
  printf "%s  │  (из бота или личного кабинета)               │%s\n" "$C$B" "$N"
  printf "%s  └─────────────────────────────────────────────┘%s\n" "$C$B" "$N"
fi
while :; do
  if [ -z "$SUB" ]; then printf "%s  Ссылка: %s" "$B" "$N"; read SUB </dev/tty 2>/dev/null; fi
  SUB="${SUB%/}"
  OKD=0; for d in $SUB_HOSTS; do case "$SUB" in https://$d/*|http://$d/*) OKD=1;; esac; done
  if [ "$OKD" = 1 ]; then break; fi
  warn "Это не ссылка Geodema (нужен домен: $SUB_HOSTS). Повтори."; SUB=
done
log "[4/6] Ссылка принята"

# ── [5/6] HWID + конфиг + правки ──
info "[5/6] Загрузка конфига + настройка..."
HWIDFILE=/opt/clash/.hwid
if [ -f "$HWIDFILE" ]; then HWID=$(cat "$HWIDFILE"); else
  MAC=$(cat /sys/class/net/eth0/address 2>/dev/null | tr -d ':'); [ -z "$MAC" ] && MAC=$(head -c16 /dev/urandom 2>/dev/null | md5sum | cut -c1-12)
  HWID="ssclash-$MAC"; echo "$HWID" > "$HWIDFILE"; fi
curl -s --max-time 40 -H "x-hwid: $HWID" -H "x-device-os: Linux" -H "x-ver-os: OpenWrt" -H "x-device-model: Router" -o /opt/clash/config.yaml "${SUB}/mihomo"
grep -q '^mixed-port' /opt/clash/config.yaml 2>/dev/null || die "подписка вернула не mihomo-конфиг"
grep -q 'App not supported' /opt/clash/config.yaml && die "лимит устройств (HWID) — сбрось привязки в боте/ЛК и повтори"
# правки совместимости с SSClash
echo 'PROXY_MODE=tun' > /opt/clash/settings
grep -q 'device: clash-tun' /opt/clash/config.yaml || sed -i '/^tun:/a\  device: clash-tun' /opt/clash/config.yaml
sed -i 's/stack: mixed/stack: system/' /opt/clash/config.yaml
grep -q 'listen: 0.0.0.0:7874' /opt/clash/config.yaml || sed -i '/^dns:/a\  listen: 0.0.0.0:7874' /opt/clash/config.yaml
# дашборд: external-controller на все интерфейсы (иначе морда недоступна)
if grep -q '^external-controller:' /opt/clash/config.yaml; then
  sed -i 's/^external-controller:.*/external-controller: 0.0.0.0:9090/' /opt/clash/config.yaml
else printf 'external-controller: 0.0.0.0:9090\n' >> /opt/clash/config.yaml; fi
grep -q '^external-ui:' /opt/clash/config.yaml || printf 'external-ui: ./ui\n' >> /opt/clash/config.yaml
log "[5/6] настроено (DNS/TUN/дашборд)"

# ── [6/6] запуск ──
info "[6/6] Запуск..."
/etc/init.d/clash enable >/dev/null 2>&1
/etc/init.d/clash restart >/dev/null 2>&1
rm -rf /tmp/luci-indexcache* /tmp/luci-modulecache
/etc/init.d/rpcd restart 2>/dev/null; /etc/init.d/uhttpd restart 2>/dev/null
sleep 12
EXIT=$(curl -s --max-time 15 http://ip-api.com/line?fields=country,query 2>/dev/null | tr '\n' ' ')
IP=$(uci -q get network.lan.ipaddr 2>/dev/null); [ -z "$IP" ] && IP="<ip-роутера>"
echo
printf "%s  ✅ Готово! VPN запущен.%s\n" "$G$B" "$N"
[ -n "$EXIT" ] && log "Выход в интернет: $EXIT"
echo "     • Вкл/выкл:  LuCI → Services → SSClash"
echo "     • Дашборд:   http://$IP:9090/ui   (или кнопка Dashboard в SSClash)"
printf "%s  ──────────────────────────────────────────────%s\n" "$C" "$N"
