#!/bin/bash
# ==========================================
# AEA SERVER MODULE: SMART GATEWAY (CLOUD VPS)
# VERSION: 1.24 (Smart Split Routing Support)
# ==========================================
AEA_VERSION="1.24"
MODULE_DATE="2026-05-24"

INFO_FILE="/etc/aea_gateway.info"
DATA_DIR="/opt/aea_gateway"

# Подхватываем параметры из макросов Android-приложения
BASE_INBOUND_PORT="{{APP_PORT_GATEWAY}}"
[[ "$BASE_INBOUND_PORT" == "{{"* ]] && BASE_INBOUND_PORT=41443

INBOUND_SNI="{{INBOUND_SNI}}"
[[ "$INBOUND_SNI" == "{{"* ]] && INBOUND_SNI="vk.com"

GATEWAY_MODE="{{GATEWAY_MODE}}"
[[ "$GATEWAY_MODE" == "{{"* ]] && GATEWAY_MODE="to_vpn"

BYPASS_ZONE="{{BYPASS_ZONE}}"
[[ "$BYPASS_ZONE" == "{{"* ]] && BYPASS_ZONE="auto"

NEXT_HOP_IP="{{NEXT_HOP_IP}}"
NEXT_HOP_PORT="{{NEXT_HOP_PORT}}"
NEXT_HOP_UUID="{{NEXT_HOP_UUID}}"
NEXT_HOP_SNI="{{NEXT_HOP_SNI}}"
[[ "$NEXT_HOP_SNI" == "{{"* ]] && NEXT_HOP_SNI="bing.com"
NEXT_HOP_PBK="{{NEXT_HOP_PBK}}"
NEXT_HOP_SID="{{NEXT_HOP_SID}}"

generate_route_rules() {
    local mode=$1
    local zone=$2

    # ИСПРАВЛЕНИЕ: Если зона пустая, генерируем базовые правила без разделения
    if [ -z "$zone" ] || [ "$zone" == "none" ]; then
        echo "[
            { \"inbound\": [\"inbound-vless\"], \"action\": \"sniff\" },
            { \"inbound\": [\"inbound-vless\"], \"network\": \"tcp\", \"outbound\": \"tunnel-next-hop\" },
            { \"inbound\": [\"inbound-vless\"], \"network\": \"udp\", \"outbound\": \"tunnel-next-hop\" }
        ]"
        return
    fi

    local suffixes="[\".$zone\"]"

    if [ "$zone" == "ru" ]; then
        suffixes="[\".ru\", \".su\", \".xn--p1ai\", \"vk.com\", \"yandex.net\", \"yandex.ru\", \"mail.ru\", \"gosuslugi.ru\", \"kinopoisk.ru\"]"
    elif [ "$zone" == "ir" ]; then
        suffixes="[\".ir\", \"sanjesh.org\", \"divar.ir\", \"snapp.ir\", \"shaparak.ir\"]"
    elif [ "$zone" == "cn" ]; then
        suffixes="[\".cn\", \"baidu.com\", \"taobao.com\", \"qq.com\", \"alipay.com\"]"
    fi

    if [ "$mode" == "to_vpn" ]; then
        echo "[
            { \"inbound\": [\"inbound-vless\"], \"action\": \"sniff\" },
            { \"domain_suffix\": $suffixes, \"outbound\": \"direct-out\" },
            { \"rule_set\": [\"geoip-$zone\"], \"outbound\": \"direct-out\" },
            { \"inbound\": [\"inbound-vless\"], \"network\": \"tcp\", \"outbound\": \"tunnel-next-hop\" },
            { \"inbound\": [\"inbound-vless\"], \"network\": \"udp\", \"outbound\": \"tunnel-next-hop\" }
        ]"
    else
        echo "[
            { \"inbound\": [\"inbound-vless\"], \"action\": \"sniff\" },
            { \"inbound\": [\"inbound-vless\"], \"network\": \"tcp\", \"outbound\": \"tunnel-next-hop\" },
            { \"inbound\": [\"inbound-vless\"], \"network\": \"udp\", \"outbound\": \"tunnel-next-hop\" }
        ]"
    fi
}

if [ "$1" == "--version" ] || [ "$1" == "-v" ]; then
    echo "$AEA_VERSION"
    exit 0
fi

if [ "$1" == "--info" ]; then
    if [ -f "$INFO_FILE" ]; then
        base64 -d "$INFO_FILE"
    else
        echo '{"status": "not_installed"}'
    fi
    exit 0
fi

if [ "$1" == "--cli" ]; then
    if [ ! -f "$DATA_DIR/config.json" ]; then
        echo "[AEA] Error: Core configuration components not found."
        exit 1
    fi

    case $2 in
        add_client)
            NEW_UUID=$(cat /proc/sys/kernel/random/uuid)
            jq --arg uuid "$NEW_UUID" '.inbounds[0].users += [{"uuid": $uuid, "flow": "xtls-rprx-vision"}]' "$DATA_DIR/config.json" > "$DATA_DIR/tmp.json" && mv "$DATA_DIR/tmp.json" "$DATA_DIR/config.json"
            docker restart aea_smart_gateway >/dev/null 2>&1
            echo "{\"status\": \"success\", \"uuid\": \"$NEW_UUID\"}"
            ;;
        remove_client)
            DEL_UUID=$3
            jq --arg uuid "$DEL_UUID" '.inbounds[0].users |= map(select(.uuid != $uuid))' "$DATA_DIR/config.json" > "$DATA_DIR/tmp.json" && mv "$DATA_DIR/tmp.json" "$DATA_DIR/config.json"
            docker restart aea_smart_gateway >/dev/null 2>&1
            echo "{\"status\": \"success\"}"
            ;;
        set_mode)
            NEW_MODE=$3
            CURRENT_INFO=$(base64 -d "$INFO_FILE")
            CURRENT_ZONE=$(echo "$CURRENT_INFO" | jq -r '.bypass_zone')
            RULES=$(generate_route_rules "$NEW_MODE" "$CURRENT_ZONE")
            jq --argjson rules "$RULES" '.route.rules = $rules' "$DATA_DIR/config.json" > "$DATA_DIR/tmp.json" && mv "$DATA_DIR/tmp.json" "$DATA_DIR/config.json"
            docker restart aea_smart_gateway >/dev/null 2>&1
            UPDATED_INFO=$(echo "$CURRENT_INFO" | jq --arg mode "$NEW_MODE" '.mode = $mode')
            echo "$UPDATED_INFO" | base64 > "$INFO_FILE"
            echo "{\"status\": \"success\", \"mode\": \"$NEW_MODE\"}"
            ;;
    esac
    exit 0
fi

if [ "$1" == "--remove" ]; then
    echo "[AEA] Removing Smart Gateway components from system environment..."
    if [ -f "$INFO_FILE" ]; then
        JSON=$(base64 -d "$INFO_FILE")
        OLD_PORT=$(echo "$JSON" | grep -oP '"inbound_port": \K\d+')
        if command -v ufw >/dev/null 2>&1; then
            [ -n "$OLD_PORT" ] && ufw delete allow "$OLD_PORT"/tcp >/dev/null 2>&1
            [ -n "$OLD_PORT" ] && ufw delete allow "$OLD_PORT"/udp >/dev/null 2>&1
        fi
    fi
    docker rm -f aea_smart_gateway >/dev/null 2>&1
    rm -rf "$DATA_DIR"
    rm -f "$INFO_FILE"
    rm -f /usr/local/bin/aea_gateway
    echo "[AEA] Module successfully removed."
    exit 0
fi

echo "[AEA] Initializing Smart Gateway module components..."

# Очистка сети и остановка старых процессов перед скачиванием
echo "[AEA] Cleaning up previous network interfaces and containers..."
systemctl stop aea_gateway >/dev/null 2>&1 || true
docker stop aea_smart_gateway >/dev/null 2>&1 || true
ip link delete tun0 >/dev/null 2>&1 || true

INBOUND_PORT=$BASE_INBOUND_PORT

while ss -tuln | grep -q ":$INBOUND_PORT " || netstat -tuln | grep -q ":$INBOUND_PORT "; do
    INBOUND_PORT=$((INBOUND_PORT + 10))
done

if ! command -v docker >/dev/null 2>&1 || ! command -v jq >/dev/null 2>&1; then
    export DEBIAN_FRONTEND=noninteractive
    apt-get update -yq >/dev/null 2>&1
    apt-get install -yq docker.io jq curl wget >/dev/null 2>&1
    systemctl enable --now docker >/dev/null 2>&1
fi

echo "[AEA] Synchronizing system time via NTP..."
export DEBIAN_FRONTEND=noninteractive
apt-get install -yq chrony >/dev/null 2>&1
systemctl enable --now chrony >/dev/null 2>&1
chronyc makestep >/dev/null 2>&1

echo "[AEA] Deploying decentralized cryptographic storage layer..."

if ! command -v python3 >/dev/null 2>&1; then
    export DEBIAN_FRONTEND=noninteractive
    apt-get install -yq python3 >/dev/null 2>&1
fi

CRYPTO_SCRIPT_TARGET="/usr/local/bin/aea_db_crypto.py"
ASSIGNED_KEY_PATH="/etc/aea_gateway_db.key"
ASSIGNED_DB_PATH="$DATA_DIR/registry.enc"

curl -s -L "https://download.aea-aiserver.ru/mirror/aea_db_crypto.py" -o "$CRYPTO_SCRIPT_TARGET"

if [ ! -s "$CRYPTO_SCRIPT_TARGET" ]; then
    echo "[AEA] Fatal Error: Failed to fetch crypto database module from repository!"
    exit 1
fi

sed -i "s|{{CRYPTO_KEY_PATH}}|$ASSIGNED_KEY_PATH|g" "$CRYPTO_SCRIPT_TARGET"
sed -i "s|{{CRYPTO_DB_PATH}}|$ASSIGNED_DB_PATH|g" "$CRYPTO_SCRIPT_TARGET"

chmod 700 "$CRYPTO_SCRIPT_TARGET"
chown root:root "$CRYPTO_SCRIPT_TARGET"

if [ ! -f "$ASSIGNED_DB_PATH" ]; then
    echo "[AEA] Initializing secure encrypted database registry..."
    "$CRYPTO_SCRIPT_TARGET" --init >/dev/null 2>&1
else
    echo "[AEA] Existing encrypted database registry detected. Skipping initialization."
fi
echo "[AEA] Cryptographic storage layer successfully configured."

mkdir -p "$DATA_DIR"
ADMIN_UUID=$(cat /proc/sys/kernel/random/uuid)

# ==============================================================================
# === ИСПРАВЛЕНИЕ: ПРОВЕРКА НА ОТКЛЮЧЕННОЕ РАЗДЕЛЕНИЕ ТРАФИКА ===
# ==============================================================================
TARGET_ZONE="$BYPASS_ZONE"
ROUTE_RULE_SET="[]"

if [ -n "$TARGET_ZONE" ] && [ "$TARGET_ZONE" != "none" ]; then
    if [ "$TARGET_ZONE" == "auto" ]; then
        echo "[AEA] Detecting system country location automatically..."
        DETECTED_CC=$(curl -s --max-time 5 https://ipapi.co/country/ | tr '[:upper:]' '[:lower:]')
        if [ -n "$DETECTED_CC" ] && [ ${#DETECTED_CC} -eq 2 ]; then
            TARGET_ZONE="$DETECTED_CC"
            echo "[AEA] Auto-detected country zone: $TARGET_ZONE"
        else
            TARGET_ZONE="ru"
            echo "[AEA] Auto-detection failed. Using default target zone: ru"
        fi
    fi

    rm -f "$DATA_DIR"/*.srs
    echo "[AEA] Fetching valid routing rule-sets for target zone: $TARGET_ZONE..."
    curl -Lo "$DATA_DIR/geoip-${TARGET_ZONE}.srs" "https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/sing/geo/geoip/${TARGET_ZONE}.srs"

    if [ ! -s "$DATA_DIR/geoip-${TARGET_ZONE}.srs" ]; then
        echo "[AEA] Warning: Target zone rule-set not found. Using generic fallback."
        curl -Lo "$DATA_DIR/geoip-${TARGET_ZONE}.srs" "https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/sing/geo/geoip/private.srs"
    fi
    
    # Динамически собираем блок rule_set
    ROUTE_RULE_SET="[ { \"tag\": \"geoip-${TARGET_ZONE}\", \"type\": \"local\", \"format\": \"binary\", \"path\": \"/etc/sing-box/geoip-${TARGET_ZONE}.srs\" } ]"
else
    echo "[AEA] Split routing disabled. Forwarding all traffic directly to next hop."
fi

ROUTE_RULES=$(generate_route_rules "$GATEWAY_MODE" "$TARGET_ZONE")

FLOW_SETTING="\"flow\": \"xtls-rprx-vision\","
if [ "$GATEWAY_MODE" == "to_gateway" ]; then
    FLOW_SETTING=""
fi

echo "[AEA] Building core node configuration..."
cat <<EOF > "$DATA_DIR/config.json"
{
  "log": { "level": "warn" },
  "dns": {
    "servers": [ { "tag": "dns-google", "type": "udp", "server": "8.8.8.8" } ],
    "final": "dns-google",
    "strategy": "ipv4_only"
  },
  "inbounds": [
    {
      "type": "vless",
      "tag": "inbound-vless",
      "listen": "0.0.0.0",
      "listen_port": $INBOUND_PORT,
      "users": [ { "uuid": "$ADMIN_UUID", "flow": "xtls-rprx-vision" } ],
      "tls": {
        "enabled": true,
        "server_name": "$INBOUND_SNI",
        "reality": {
          "enabled": true,
          "handshake": { "server": "$INBOUND_SNI", "server_port": 443 },
          "private_key": "",
          "short_id": []
        }
      }
    }
  ],
  "outbounds": [
    { "type": "direct", "tag": "direct-out" },
    {
      "type": "vless",
      "tag": "tunnel-next-hop",
      "server": "$NEXT_HOP_IP",
      "server_port": $NEXT_HOP_PORT,
      "uuid": "$NEXT_HOP_UUID",
      $FLOW_SETTING
      "packet_encoding": "xudp",
      "tls": {
        "enabled": true,
        "server_name": "$NEXT_HOP_SNI",
        "utls": { "enabled": true, "fingerprint": "chrome" }
      }
    }
  ],
  "route": {
    "rule_set": $ROUTE_RULE_SET,
    "default_domain_resolver": "dns-google",
    "rules": $ROUTE_RULES
  }
}
EOF

REALITY_KEYS=$(docker run --rm ghcr.io/sagernet/sing-box:latest generate reality-keypair)
LOCAL_PRIVATE_KEY=$(echo "$REALITY_KEYS" | grep "PrivateKey" | awk '{print $2}')
LOCAL_PUBLIC_KEY=$(echo "$REALITY_KEYS" | grep "PublicKey" | awk '{print $2}')
LOCAL_SHORT_ID=$(cat /dev/urandom | tr -dc 'a-f0-9' | fold -w 16 | head -n 1)

jq --arg pk "$LOCAL_PRIVATE_KEY" --arg sid "$LOCAL_SHORT_ID" '.inbounds[0].tls.reality.private_key = $pk | .inbounds[0].tls.reality.short_id = [$sid]' "$DATA_DIR/config.json" > "$DATA_DIR/tmp.json" && mv "$DATA_DIR/tmp.json" "$DATA_DIR/config.json"

if [ -n "$NEXT_HOP_PBK" ] && [[ "$NEXT_HOP_PBK" != "{{"* ]]; then
    jq --arg pbk "$NEXT_HOP_PBK" --arg sid "$NEXT_HOP_SID" '.outbounds[1].tls += {"reality": {"enabled": true, "public_key": $pbk, "short_id": $sid}}' "$DATA_DIR/config.json" > "$DATA_DIR/tmp.json" && mv "$DATA_DIR/tmp.json" "$DATA_DIR/config.json"
fi

if command -v ufw >/dev/null 2>&1; then
    ufw allow "$INBOUND_PORT"/tcp >/dev/null 2>&1
    ufw allow "$INBOUND_PORT"/udp >/dev/null 2>&1
fi

docker rm -f aea_smart_gateway >/dev/null 2>&1
docker run -d --name aea_smart_gateway --restart unless-stopped --network host -v "$DATA_DIR":/etc/sing-box ghcr.io/sagernet/sing-box:latest run -c /etc/sing-box/config.json >/dev/null 2>&1

JSON_DATA="{\"status\": \"success\", \"inbound_port\": $INBOUND_PORT, \"inbound_sni\": \"$INBOUND_SNI\", \"admin_uuid\": \"$ADMIN_UUID\", \"public_key\": \"$LOCAL_PUBLIC_KEY\", \"short_id\": \"$LOCAL_SHORT_ID\", \"mode\": \"$GATEWAY_MODE\", \"bypass_zone\": \"$TARGET_ZONE\"}"
echo "$JSON_DATA" | base64 > "$INFO_FILE"
chmod 600 "$INFO_FILE"

MODULE_PATH="/usr/local/bin/aea_gateway"
cat "$0" > "$MODULE_PATH"
chmod +x "$MODULE_PATH"

exit 0
