#!/bin/bash

# ==============================================================================
# Nginx TCP/UDP 转发代理自动化安装脚本
# ==============================================================================
set -e

# 步骤 0: 欢迎信息和获取用户输入
# ==============================================================================
echo "欢迎使用 Nginx TCP/UDP 转发代理自动化安装脚本"
echo "请根据提示输入配置信息，所有项目均为必填项。"
echo "------------------------------------------------------------"

# 获取监听端口 (强制输入)
while true; do
    read -p "请输入 Nginx 对外监听的端口 (1-65535): " LISTEN_PORT
    if [[ -z "$LISTEN_PORT" ]]; then
        echo "-> 输入不能为空，请重新输入。"
    elif ! [[ "$LISTEN_PORT" =~ ^[0-9]+$ ]]; then
        echo "-> 输入格式错误，请输入纯数字的端口号。"
    elif [[ "$LISTEN_PORT" -lt 1 || "$LISTEN_PORT" -gt 65535 ]]; then
        echo "-> 端口号范围无效，请输入一个 1-65535 之间的端口号。"
    else
        break # 输入有效，跳出循环
    fi
done

# 获取后端服务器 IP 或域名 (强制输入)
while true; do
    read -p "请输入后端服务器的 IP 地址或域名: " BACKEND_IP
    if [[ -z "$BACKEND_IP" ]]; then
        echo "-> 输入不能为空，请输入一个有效的 IP 地址或域名。"
    else
        break
    fi
done

# 获取后端服务器端口 (强制输入)
while true; do
    read -p "请输入后端服务器的端口 (1-65535): " BACKEND_PORT
    if [[ -z "$BACKEND_PORT" ]]; then
        echo "-> 输入不能为空，请重新输入。"
    elif ! [[ "$BACKEND_PORT" =~ ^[0-9]+$ ]]; then
        echo "-> 输入格式错误，请输入纯数字的端口号。"
    elif [[ "$BACKEND_PORT" -lt 1 || "$BACKEND_PORT" -gt 65535 ]]; then
        echo "-> 端口号范围无效，请输入一个 1-65535 之间的端口号。"
    else
        break # 输入有效，跳出循环
    fi
done

# 检查 Root 权限
if [ "$(id -u)" -ne 0 ]; then
    echo "-> 此脚本需要以 root 权限运行，请使用 'sudo bash $0' 执行。"
    exit 1
fi

# 变量定义
STREAM_CONFIG_FILE="/etc/nginx/conf.d/proxy-${LISTEN_PORT}.stream"
MAIN_CONFIG_FILE="/etc/nginx/nginx.conf"
STREAM_INCLUDE_DIRECTIVE="include /etc/nginx/conf.d/*.stream;"

echo ""
echo "-> 即将开始 Nginx 转发代理自动化部署..."
echo "----------------------------------------"
echo "  配置确认:"
echo "  - 本机服务端口: ${LISTEN_PORT}"
echo "  - 后端服务地址: ${BACKEND_IP}"
echo "  - 后端服务端口: ${BACKEND_PORT}"
echo "----------------------------------------"
echo "配置将在 3 秒后开始执行..."
sleep 3

# 步骤 1: 卸载旧版 Nginx
# ==============================================================================
echo "--- [1/5] 正在卸载旧版 Nginx (如果存在)... ---"
systemctl stop nginx >/dev/null 2>&1 || true
apt-get purge nginx nginx-common nginx-core -y >/dev/null 2>&1
apt-get autoremove -y >/dev/null 2>&1
rm -f /etc/apt/sources.list.d/nginx.list
echo "-> 旧版 Nginx 清理完毕。"

# 步骤 2: 从 Nginx 官方源安装 Nginx
# ==============================================================================
echo "--- [2/5] 正在安装 Nginx 官方源并安装新版 Nginx... ---"
apt-get update >/dev/null
apt-get install -y curl gnupg2 ca-certificates lsb-release debian-archive-keyring >/dev/null
curl -fsSL https://nginx.org/keys/nginx_signing.key | gpg --dearmor -o /usr/share/keyrings/nginx-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] http://nginx.org/packages/mainline/debian `lsb_release -cs` nginx" | tee /etc/apt/sources.list.d/nginx.list >/dev/null
apt-get update >/dev/null
apt-get install -y nginx >/dev/null
echo "-> Nginx 最新稳定版安装成功。"

# 步骤 3: 创建 Stream 转发配置文件
# ==============================================================================
echo "--- [3/5] 正在创建 TCP/UDP 转发配置文件... ---"
mkdir -p /etc/nginx/conf.d
# 使用 cat 和 EOF 来写入多行配置, 并使用变量
cat > "$STREAM_CONFIG_FILE" <<EOF
# TCP/UDP 转发配置: ${LISTEN_PORT} -> ${BACKEND_IP}:${BACKEND_PORT}
stream {
    upstream tcp_backend {
        zone tcp_backend_servers 64k;
        server ${BACKEND_IP}:${BACKEND_PORT};
    }

    upstream udp_backend {
        zone udp_backend_servers 64k;
        server ${BACKEND_IP}:${BACKEND_PORT};
    }

    server {
        listen ${LISTEN_PORT};
        listen [::]:${LISTEN_PORT};
        proxy_pass tcp_backend;
        #proxy_protocol on;
        proxy_connect_timeout 5s;
        proxy_timeout 1m;
    }

    server {
        listen ${LISTEN_PORT} udp;
        listen [::]:${LISTEN_PORT} udp;
        proxy_pass udp_backend;
        #proxy_protocol on;
        proxy_timeout 10s;
        proxy_responses 1;
    }
}
EOF
echo "-> 转发配置文件 '${STREAM_CONFIG_FILE}' 创建成功。"

# 步骤 4: 修改主配置文件以加载 Stream 配置
# ==============================================================================
echo "--- [4/5] 正在修改主配置文件以加载 Stream 配置... ---"
# 检查主配置文件中是否已包含 stream 配置指令
if ! grep -q -E "^\s*include\s+/etc/nginx/conf.d/\*\.stream;" "$MAIN_CONFIG_FILE"; then
    # 如果 http {} 块存在，则在其上方插入 stream 配置指令，否则追加到文件末尾
    if grep -q "http {" "$MAIN_CONFIG_FILE"; then
        sed -i '/http {/i \
# 加载所有 stream (TCP/UDP) 相关的配置 \
include /etc/nginx/conf.d/*.stream; \
' "$MAIN_CONFIG_FILE"
    else
        echo -e "\n# 加载所有 stream (TCP/UDP) 相关的配置\n$STREAM_INCLUDE_DIRECTIVE" >> "$MAIN_CONFIG_FILE"
    fi
    echo "-> 主配置文件 '${MAIN_CONFIG_FILE}' 修改成功。"
else
    echo "-> Stream 配置加载指令已存在，无需修改。"
fi

# 步骤 5: 测试配置并启动服务
# ==============================================================================
echo "--- [5/5] 正在测试配置并启动 Nginx 服务... ---"
if nginx -t; then
    systemctl restart nginx
    systemctl enable nginx
    echo "-> Nginx 配置测试通过，服务已启动并设置为开机自启。"
else
    echo "-> Nginx 配置测试失败！请检查配置文件中的错误。"
    exit 1
fi

echo ""
echo "-> 恭喜！Nginx 转发代理已全部署完毕！"
echo ""
systemctl status nginx --no-pager

echo ""
echo "=============================== 执行完毕 ==============================="