#!/bin/bash
#
# MC-Dispatch 一键安装脚本
# Minecraft 握手分流器 - 多节点共用 25565 端口
#

set -e

# ========== 管道模式检测 ==========
if [ ! -t 0 ]; then
    _TMP=$(mktemp /tmp/mc-dispatch-install.XXXXXX.sh)
    curl -fsSL "https://get.coexa.cx/mc-dispatch-install.sh" -o "$_TMP"
    chmod +x "$_TMP"
    exec bash "$_TMP" "$@"
fi

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

info()  { echo -e "${GREEN}[INFO]${NC} $1"; }
warn()  { echo -e "${YELLOW}[WARN]${NC} $1"; }
error() { echo -e "${RED}[ERROR]${NC} $1"; exit 1; }

[[ $EUID -ne 0 ]] && error "请使用 root 用户运行此脚本"

INSTALL_DIR="/usr/local/bin"
CONFIG_DIR="/etc/mc-dispatch"
CONFIG_FILE="$CONFIG_DIR/config.json"
SERVICE_FILE="/etc/systemd/system/mc-dispatch.service"
DOWNLOAD_BASE="https://get.coexa.cx"

ARCH=$(uname -m)
case "$ARCH" in
    x86_64)  BIN_NAME="mc-dispatch-linux-amd64" ;;
    aarch64) BIN_NAME="mc-dispatch-linux-arm64" ;;
    *) error "不支持的架构: $ARCH" ;;
esac

echo ""
echo -e "${CYAN}========================================${NC}"
echo -e "${CYAN}  MC-Dispatch 分流器${NC}"
echo -e "${CYAN}  Minecraft 握手分流 · 多节点共用端口${NC}"
echo -e "${CYAN}========================================${NC}"
echo ""
echo -e "  ${GREEN}1)${NC} 安装 / 重新配置"
echo -e "  ${GREEN}2)${NC} 添加路由规则"
echo -e "  ${GREEN}3)${NC} 查看当前配置"
echo -e "  ${GREEN}4)${NC} 卸载"
echo ""
printf "%b" "${GREEN}请选择 ${YELLOW}[1-4]${NC}: "
read -r CHOICE

case "$CHOICE" in
1)
    # ===== 安装 =====
    info "下载 mc-dispatch..."
    curl -fSL -o "$INSTALL_DIR/mc-dispatch" "$DOWNLOAD_BASE/$BIN_NAME" || error "下载失败"
    chmod +x "$INSTALL_DIR/mc-dispatch"
    info "已安装到 $INSTALL_DIR/mc-dispatch"

    mkdir -p "$CONFIG_DIR"

    # 监听端口
    printf "%b" "${GREEN}监听端口${NC} [默认 25565]: "
    read -r LISTEN_PORT
    LISTEN_PORT=${LISTEN_PORT:-25565}

    # 默认后端（可选）
    printf "%b" "${GREEN}默认后端${NC} (无匹配时转发到这里，留空跳过): "
    read -r DEFAULT_BACKEND
    # 自动补端口
    [[ -n "$DEFAULT_BACKEND" && "$DEFAULT_BACKEND" != *:* ]] && DEFAULT_BACKEND="${DEFAULT_BACKEND}:25565"

    # 添加路由
    ROUTES="[]"
    while true; do
        echo ""
        printf "%b" "${GREEN}添加路由? ${YELLOW}[y/N]${NC}: "
        read -r ADD_ROUTE
        [[ "$ADD_ROUTE" != "y" && "$ADD_ROUTE" != "Y" ]] && break

        printf "%b" "${GREEN}  MC 服务器地址${NC} (如 play.hypixel.net): "
        read -r MC_ADDR
        [[ -z "$MC_ADDR" ]] && { warn "地址不能为空"; continue; }

        printf "%b" "${GREEN}  后端节点${NC} (如 1.2.3.4:25565): "
        read -r BACKEND
        [[ -z "$BACKEND" ]] && { warn "后端不能为空"; continue; }
        # 自动补端口
        [[ "$BACKEND" != *:* ]] && BACKEND="${BACKEND}:25565"

        ROUTES=$(echo "$ROUTES" | python3 -c "
import sys, json
routes = json.load(sys.stdin)
routes.append({'serverAddress': '$MC_ADDR', 'backend': '$BACKEND'})
print(json.dumps(routes))
" 2>/dev/null || echo "$ROUTES")
        info "已添加: $MC_ADDR -> $BACKEND"
    done

    # 写配置
    DEFAULT_FIELD=""
    if [[ -n "$DEFAULT_BACKEND" ]]; then
        DEFAULT_FIELD="\"default\": \"$DEFAULT_BACKEND\","
    fi

    python3 -c "
import json
routes = json.loads('$ROUTES')
config = {
    'listen': '0.0.0.0:$LISTEN_PORT',
    'routes': routes,
    'logLevel': 'info'
}
default_backend = '$DEFAULT_BACKEND'
if default_backend:
    config['default'] = default_backend
with open('$CONFIG_FILE', 'w') as f:
    json.dump(config, f, indent=2, ensure_ascii=False)
print('配置已写入')
"

    info "配置文件: $CONFIG_FILE"
    cat "$CONFIG_FILE"

    # systemd service
    cat > "$SERVICE_FILE" << EOF
[Unit]
Description=MC-Dispatch Minecraft Handshake Router
After=network.target

[Service]
Type=simple
ExecStart=$INSTALL_DIR/mc-dispatch $CONFIG_FILE
Restart=on-failure
RestartSec=5
LimitNOFILE=65535

[Install]
WantedBy=multi-user.target
EOF

    systemctl daemon-reload
    systemctl enable mc-dispatch
    systemctl restart mc-dispatch
    sleep 1

    if systemctl is-active --quiet mc-dispatch; then
        info "mc-dispatch 已启动 ✅"
        echo ""
        echo -e "${CYAN}===== 当前路由表 =====${NC}"
        python3 -c "
import json
with open('$CONFIG_FILE') as f:
    c = json.load(f)
print(f\"监听: {c['listen']}\")
for r in c.get('routes', []):
    print(f\"  {r['serverAddress']} -> {r['backend']}\")
if c.get('default'):
    print(f\"  (默认) -> {c['default']}\")
"
    else
        error "启动失败，请检查: journalctl -u mc-dispatch -n 20"
    fi
    ;;

2)
    # ===== 添加路由 =====
    [[ ! -f "$CONFIG_FILE" ]] && error "未安装，请先选择 1 安装"

    printf "%b" "${GREEN}MC 服务器地址${NC} (如 play.hypixel.net): "
    read -r MC_ADDR
    [[ -z "$MC_ADDR" ]] && error "地址不能为空"

    printf "%b" "${GREEN}后端节点${NC} (如 1.2.3.4:25565): "
    read -r BACKEND
    [[ -z "$BACKEND" ]] && error "后端不能为空"
    # 自动补端口
    [[ "$BACKEND" != *:* ]] && BACKEND="${BACKEND}:25565"

    python3 -c "
import json
with open('$CONFIG_FILE') as f:
    config = json.load(f)
config.setdefault('routes', []).append({
    'serverAddress': '$MC_ADDR',
    'backend': '$BACKEND'
})
with open('$CONFIG_FILE', 'w') as f:
    json.dump(config, f, indent=2, ensure_ascii=False)
print('路由已添加')
"
    systemctl restart mc-dispatch
    info "$MC_ADDR -> $BACKEND ✅"
    ;;

3)
    # ===== 查看配置 =====
    [[ ! -f "$CONFIG_FILE" ]] && error "未安装"
    echo ""
    echo -e "${CYAN}===== MC-Dispatch 配置 =====${NC}"
    python3 -c "
import json
with open('$CONFIG_FILE') as f:
    c = json.load(f)
print(f\"监听: {c['listen']}\")
print(f\"路由:\")
for r in c.get('routes', []):
    print(f\"  {r['serverAddress']} -> {r['backend']}\")
if c.get('default'):
    print(f\"  (默认) -> {c['default']}\")
print()
print(f\"服务状态:\", end=' ')
"
    systemctl is-active mc-dispatch && echo "" || echo ""
    echo ""
    echo -e "${GREEN}客户端 SS 链接示例:${NC}"
    python3 -c "
import json
with open('$CONFIG_FILE') as f:
    c = json.load(f)
port = c['listen'].split(':')[-1]
for r in c.get('routes', []):
    sa = r['serverAddress']
    print(f'  plugin=minecraft;server={sa};port={port}')
"
    ;;

4)
    # ===== 卸载 =====
    systemctl stop mc-dispatch 2>/dev/null
    systemctl disable mc-dispatch 2>/dev/null
    rm -f "$SERVICE_FILE" "$INSTALL_DIR/mc-dispatch"
    rm -rf "$CONFIG_DIR"
    systemctl daemon-reload
    info "已卸载 mc-dispatch"
    ;;

*)
    error "无效选择"
    ;;
esac
