#!/bin/bash

# NEXX Agent Installation Script
# Установка: curl -sSL https://nexios.ru/nexx/install.sh | bash

set -e

RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'


COUNTRY=$(curl -s --max-time 5 https://ipinfo.io/country 2>/dev/null || echo "RU")
if [ "$COUNTRY" = "RU" ]; then
    NEXIOS_URL="https://nexios.ru"
    FALLBACK_URL="https://am-mj-1.nexios.ru"
else
    NEXIOS_URL="https://am-mj-1.nexios.ru"
    FALLBACK_URL="https://nexios.ru"
fi
echo "[INFO] Регион: $COUNTRY, primary: $NEXIOS_URL"

INSTALL_DIR="/opt/nexx-agent"
SERVER_ID="vps-$(hostname)-$(date +%s | tail -c 5)"
MIN_SPEED=102400  # 100 KB/s минимальная скорость

log_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
log_error() { echo -e "${RED}[ERROR]${NC} $1"; exit 1; }
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }

# Функция скачивания с fallback
download_file() {
    local filename="$1"
    local output="$2"
    local url1="$NEXIOS_URL/nexx/$filename"
    local url2="$FALLBACK_URL/nexx/$filename"
    
    log_info "Скачиваем $filename..."
    
    local speed=$(curl -#L --max-time 15 -o "$output" -w "%{speed_download}" "$url1" || echo "0")
    speed=${speed%.*}
    
    if [ -f "$output" ] && [ -s "$output" ] && [ "$speed" -gt "$MIN_SPEED" ]; then
        log_info "$filename: $(numfmt --to=iec-i --suffix=B/s $speed 2>/dev/null || echo "${speed} B/s") с nexios.ru"
        return 0
    fi
    
    log_warn "$filename медленно с nexios.ru, пробуем stoneblack.ru..."
    rm -f "$output"
    
    speed=$(curl -#L --max-time 120 -o "$output" -w "%{speed_download}" "$url2" || echo "0")
    speed=${speed%.*}
    
    if [ -f "$output" ] && [ -s "$output" ]; then
        log_info "$filename: $(numfmt --to=iec-i --suffix=B/s $speed 2>/dev/null || echo "${speed} B/s") с stoneblack.ru"
        return 0
    fi
    
    log_error "Не удалось скачать $filename"
}

# Установка Cloudflare WARP
install_warp() {
    echo ""
    echo "========================================="
    log_info "📡 Установка Cloudflare WARP..."
    echo "========================================="

    # Ждём пока освободится apt lock
    local WAIT=0
    while fuser /var/lib/dpkg/lock-frontend >/dev/null 2>&1 || fuser /var/lib/apt/lists/lock >/dev/null 2>&1; do
        log_warn "apt locked, ждём... (${WAIT}s)"
        sleep 5
        WAIT=$((WAIT + 5))
        if [ $WAIT -gt 600 ]; then
            log_warn "apt locked >10min, пропускаем WARP"
            return 1
        fi
    done

    # Определяем кодовое имя дистрибутива
    local CODENAME=$(lsb_release -cs 2>/dev/null || echo "noble")
    
    curl -fsSL https://pkg.cloudflareclient.com/pubkey.gpg | gpg --yes --dearmor --output /usr/share/keyrings/cloudflare-warp-archive-keyring.gpg
    echo "deb [signed-by=/usr/share/keyrings/cloudflare-warp-archive-keyring.gpg] https://pkg.cloudflareclient.com/ ${CODENAME} main" > /etc/apt/sources.list.d/cloudflare-client.list
    
    apt update -qq
    DEBIAN_FRONTEND=noninteractive apt install -y cloudflare-warp

    log_info "Регистрация и переключение в proxy режим..."
    warp-cli --accept-tos registration new || true
    warp-cli --accept-tos mode proxy
    warp-cli --accept-tos connect
    sleep 3

    log_info "Тестирование WARP..."
    local RESULT=$(curl -s -x socks5://127.0.0.1:40000 https://www.cloudflare.com/cdn-cgi/trace | grep warp || echo "")
    if [[ "$RESULT" == *"warp=on"* ]]; then
        log_info "✅ WARP работает: $RESULT"
        log_info "Включите WARP toggle в nexios панели для этого сервера"
        return 0
    else
        log_warn "❌ WARP не активен"
        return 1
    fi
}

if [ "$EUID" -ne 0 ]; then 
    log_error "Запустите скрипт от root"
fi

log_info "Установка NEXX Agent..."

OS=$(uname -s | tr '[:upper:]' '[:lower:]')
ARCH=$(uname -m)

case $ARCH in
    x86_64) ARCH="amd64" ;;
    aarch64|arm64) ARCH="arm64" ;;
    *) log_error "Неподдерживаемая архитектура: $ARCH" ;;
esac

log_info "Система: $OS/$ARCH"

if ! command -v curl &> /dev/null; then
    log_error "curl не найден. Установите: apt-get install curl"
fi

log_info "Создаем директории..."
mkdir -p $INSTALL_DIR/data
mkdir -p $INSTALL_DIR/configs
mkdir -p /etc/sing-box
mkdir -p /var/log

download_file "nexx-agent" "$INSTALL_DIR/nexx-agent"
chmod +x $INSTALL_DIR/nexx-agent

download_file "auto-update.sh" "$INSTALL_DIR/auto-update.sh"
chmod +x $INSTALL_DIR/auto-update.sh

download_file "sing-box" "/usr/bin/sing-box"
chmod +x /usr/bin/sing-box
log_info "sing-box установлен"

log_info "Определяем IP..."
VPS_IP=$(curl -s https://api.ipify.org 2>/dev/null || curl -s https://ifconfig.me 2>/dev/null || echo "127.0.0.1")
log_info "IP: $VPS_IP"

log_info "Создаем конфигурацию..."
cat > $INSTALL_DIR/config.yaml <<EOF
server:
  port: "8080"
  whitelist_ips:
    - "127.0.0.1"
    - "130.49.174.15"
    - "95.165.98.239"
    - "158.255.1.15"

singbox:
  config_path: "/etc/sing-box/config.json"
  binary_path: "/usr/bin/sing-box"
  server_ip: "$VPS_IP"
  server_port: 443

nexios:
  url: "https://nexios.ru"
  server_id: "$SERVER_ID"

database:
  path: "$INSTALL_DIR/data/nexx.db"

logging:
  level: "info"
  file: "/var/log/nexx-agent.log"
EOF

cat > /etc/sing-box/config.json <<EOF
{
  "log": {
    "level": "info",
    "output": "/var/log/sing-box.log"
  },
  "inbounds": [],
  "outbounds": [
    {
      "type": "direct",
      "tag": "direct"
    }
  ]
}
EOF

log_info "Создаем systemd службы..."
cat > /etc/systemd/system/nexx-agent.service <<EOF
[Unit]
Description=NEXX Agent
After=network.target

[Service]
Type=simple
User=root
WorkingDirectory=$INSTALL_DIR
ExecStart=$INSTALL_DIR/nexx-agent
Restart=always
RestartSec=10
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target
EOF

cat > /etc/systemd/system/sing-box.service <<EOF
[Unit]
Description=sing-box
After=network.target

[Service]
Type=simple
User=root
ExecStart=/usr/bin/sing-box run -c /etc/sing-box/config.json
ExecReload=/bin/kill -HUP \$MAINPID
Restart=on-failure
RestartSec=10
LimitNOFILE=infinity
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target
EOF

log_info "Настраиваем автообновление..."
CRON_LINE="0 * * * * /opt/nexx-agent/auto-update.sh >> /var/log/nexx-agent-update.log 2>&1"
{ crontab -l 2>/dev/null | grep -v "auto-update.sh" || true; echo "$CRON_LINE"; } | crontab -

log_info "Настраиваем blacklist систему..."
cat > /opt/nexx-agent/update-blacklist.sh << 'SCRIPT_END'
#!/bin/bash
BLACKLIST_URL="https://nexios.ru/black.lst"
LOCAL_FILE="/opt/nexx-agent/black.lst"
BACKUP_FILE="/opt/nexx-agent/black.lst.backup"
TEMP_FILE="/tmp/black.lst.tmp"

if ! curl -sf "$BLACKLIST_URL" -o "$TEMP_FILE"; then
    [ -f "$BACKUP_FILE" ] && cp "$BACKUP_FILE" "$LOCAL_FILE"
    exit 0
fi

REMOTE_HASH=$(md5sum "$TEMP_FILE" | awk '{print $1}')
LOCAL_HASH=$([ -f "$LOCAL_FILE" ] && md5sum "$LOCAL_FILE" | awk '{print $1}')

[ "$REMOTE_HASH" = "$LOCAL_HASH" ] && exit 0

if ! grep -vE '^(#|$)' "$TEMP_FILE" | grep -qE '^[a-zA-Z0-9.-]+$'; then
    echo "ERROR: Invalid domains format"
    exit 1
fi

mv "$TEMP_FILE" "$LOCAL_FILE"
cp "$LOCAL_FILE" "$BACKUP_FILE"

curl -sf http://localhost:8080/api/sync/trigger
echo "Blacklist updated"
SCRIPT_END

chmod +x /opt/nexx-agent/update-blacklist.sh

BLACKLIST_CRON="*/15 * * * * /opt/nexx-agent/update-blacklist.sh >> /var/log/blacklist-update.log 2>&1"
{ crontab -l 2>/dev/null | grep -v "update-blacklist.sh" || true; echo "$BLACKLIST_CRON"; } | crontab -

log_info "Загружаем blacklist..."
/opt/nexx-agent/update-blacklist.sh 2>/dev/null || true

# Установка WARP (не критично, продолжаем при ошибке)
install_warp || log_warn "WARP не установлен, продолжаем без него"

systemctl daemon-reload

log_info "Запускаем службы..."
systemctl enable nexx-agent 2>/dev/null
systemctl start nexx-agent || log_error "Не удалось запустить агент"

systemctl enable sing-box 2>/dev/null
systemctl start sing-box

sleep 2
if systemctl is-active --quiet nexx-agent; then
    log_info "Агент запущен"
else
    log_error "Агент не запустился. Логи: journalctl -u nexx-agent -n 50"
fi

log_info "Ждем создания базы данных..."
sleep 3

if [ -f "$INSTALL_DIR/data/nexx.db" ]; then
    log_info "Включаем WAL режим SQLite..."
    if command -v sqlite3 &> /dev/null; then
        sqlite3 "$INSTALL_DIR/data/nexx.db" "PRAGMA journal_mode=WAL;" >/dev/null 2>&1
        log_info "WAL режим включен"
    else
        log_warn "sqlite3 не установлен. apt install sqlite3"
    fi
else
    log_warn "База данных еще не создана"
fi

# Проверка IPv6
echo ""
echo "========================================="
echo -e "${YELLOW}📡 Проверка сетевой конфигурации...${NC}"
echo "========================================="

IPV6_STATUS=$(ip -6 addr show scope global 2>/dev/null | wc -l)
if [ "$IPV6_STATUS" -gt 0 ]; then
    echo -e "${GREEN}✓ IPv6 адрес обнаружен${NC}"
    
    if ping6 -c 1 -W 2 google.com >/dev/null 2>&1; then
        echo -e "${GREEN}✓ IPv6 подключение работает${NC}"
        echo "Агент будет использовать prefer_ipv6 стратегию"
    else
        echo -e "${YELLOW}⚠ IPv6 адрес есть, но подключение не работает${NC}"
        echo "Агент будет использовать ipv4_only стратегию"
    fi
else
    echo -e "${YELLOW}⚠ IPv6 не настроен на сервере${NC}"
    echo "Агент будет использовать ipv4_only стратегию"
fi

# Тестируем оптимальный SNI
echo ""
echo "========================================="
echo -e "${YELLOW}📡 Тестирование оптимального SNI...${NC}"
echo "========================================="

cat > $INSTALL_DIR/sni-test.sh << 'SNI_SCRIPT'
#!/bin/bash

RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
CYAN='\033[0;36m'
NC='\033[0m'

SNI_DOMAINS=(
    "google.com" "www.google.com" "mail.google.com" "drive.google.com"
    "fonts.googleapis.com" "ajax.googleapis.com"
    "microsoft.com" "www.microsoft.com" "login.microsoftonline.com"
    "outlook.office365.com" "azure.microsoft.com"
    "cloudflare.com" "www.cloudflare.com" "cdnjs.cloudflare.com" "1.1.1.1"
    "amazon.com" "aws.amazon.com" "s3.amazonaws.com"
    "apple.com" "www.apple.com" "icloud.com"
    "github.com" "githubusercontent.com" "gitlab.com"
    "stackoverflow.com" "mozilla.org" "firefox.com"
    "oracle.com" "ibm.com" "samsung.com" "intel.com"
    "nvidia.com" "amd.com" "cisco.com" "vmware.com"
    "docker.com" "kubernetes.io"
    "fastly.com" "akamai.com" "digitalocean.com"
    "linode.com" "vultr.com" "hetzner.com"
    "wikipedia.org" "wikimedia.org" "archive.org"
    "reddit.com" "medium.com" "notion.so" "slack.com" "zoom.us"
    "dropbox.com" "box.com"
    "yandex.ru" "mail.ru" "vk.com" "sber.ru" "gosuslugi.ru"
)

echo -e "${CYAN}Тестирование SNI доменов...${NC}"
echo "Проверяем TLS handshake на порту 443"
echo ""

WORKING=()

for domain in "${SNI_DOMAINS[@]}"; do
    result=$(timeout 3 openssl s_client -connect "$domain:443" -servername "$domain" </dev/null 2>&1)
    
    if echo "$result" | grep -q "Verify return code: 0"; then
        latency=$(timeout 3 curl -so /dev/null -w "%{time_connect}" "https://$domain" 2>/dev/null || echo "999")
        latency_ms=$(echo "$latency * 1000" | bc 2>/dev/null | cut -d'.' -f1 || echo "999")
        
        if [ "$latency_ms" -lt 500 ]; then
            echo -e "${GREEN}✓${NC} $domain ${GREEN}(${latency_ms}ms)${NC}"
            WORKING+=("$domain:$latency_ms")
        else
            echo -e "${YELLOW}~${NC} $domain ${YELLOW}(${latency_ms}ms slow)${NC}"
        fi
    else
        echo -e "${RED}✗${NC} $domain"
    fi
done

echo ""
echo "========================================="
echo -e "${CYAN}Лучшие SNI домены (по скорости):${NC}"
echo "========================================="

IFS=$'\n' sorted=($(for item in "${WORKING[@]}"; do echo "$item"; done | sort -t':' -k2 -n | head -10))
unset IFS

for item in "${sorted[@]}"; do
    domain=$(echo "$item" | cut -d':' -f1)
    ms=$(echo "$item" | cut -d':' -f2)
    echo -e "${GREEN}$domain${NC} - ${ms}ms"
done

echo ""
echo "Рекомендация: используйте первый домен из списка для server_name в sing-box"
SNI_SCRIPT

chmod +x $INSTALL_DIR/sni-test.sh

if command -v openssl &> /dev/null && command -v bc &> /dev/null; then
    $INSTALL_DIR/sni-test.sh
else
    log_warn "openssl или bc не установлены, SNI тест пропущен"
    log_warn "Установите: apt install openssl bc"
fi

echo ""
echo "========================================="
echo -e "${GREEN}Установка завершена!${NC}"
echo "========================================="
echo ""
echo "Server ID: $SERVER_ID"
echo "IP: $VPS_IP"
echo ""
echo "Команды:"
echo "  systemctl status nexx-agent"
echo "  journalctl -u nexx-agent -f"
echo "  $INSTALL_DIR/auto-update.sh"
echo "  $INSTALL_DIR/sni-test.sh    # Тест оптимального SNI"
echo "  warp-cli status              # Статус WARP"
echo ""
echo -e "${GREEN}Автообновление: каждый час${NC}"
echo "========================================"