#!/bin/bash
# ============================================================
#  FRPS Multi-Port Manager (V3.0 Refactored Menu)
#  交互菜单深度精简版：主菜单 -> 端口管理二级菜单
# ============================================================

BIND_PORT="7000"
FRP_TOKEN="SuperStrongRDP@2026"
FRP_VERSION="v0.58.1"
VER_NUM="0.58.1"
WORK_DIR="/root"
PORT_DB="${WORK_DIR}/frp_ports.db"

# 权限检查
if [ "$EUID" -ne 0 ]; then
    echo "[错误] 请使用 root 权限运行此脚本！"
    exit 1
fi

# 初始化端口数据库
if [ ! -f "$PORT_DB" ]; then
    touch "$PORT_DB"
fi

# 检查服务状态
get_status() {
    if systemctl is-active --quiet frps; then
        echo -e "\e[32m运行中 (Active)\e[0m"
    else
        echo -e "\e[31m已停止 (Stopped)\e[0m"
    fi
}

# 强力清理旧进程（防止幽灵进程霸占端口）
cleanup_ghost_processes() {
    echo "[清理] 正在检查是否存在残留或非托管的 frps 进程..."
    if pgrep -x "frps" > /dev/null; then
        echo "[清理] 发现正在运行的 frps 进程，正在强行终止..."
        pkill -9 -x "frps" >/dev/null 2>&1
        killall -9 frps >/dev/null 2>&1
        sleep 1
    else
        echo "[清理] 未发现残留进程，系统环境干净。"
    fi
}

# ------------------------------------------------------------
#  1. 核心安装逻辑
# ------------------------------------------------------------
install_frps() {
    echo "============================================="
    echo " 开始安装/重装 FRPS 服务"
    echo "============================================="
    
    # 自动清理老旧进程，防止端口冲突
    cleanup_ghost_processes

    # 自动识别架构
    ARCH=$(uname -m)
    case "$ARCH" in
        x86_64)        FRP_ARCH="amd64" ;;
        aarch64|arm64) FRP_ARCH="arm64" ;;
        armv7l)        FRP_ARCH="arm" ;;
        *) echo "[错误] 不支持的CPU架构：$ARCH"; exit 1 ;;
    esac
    ZIP_NAME="frp_${VER_NUM}_linux_${FRP_ARCH}.tar.gz"
    echo "[信息] 检测到架构 ${ARCH}，将下载 ${ZIP_NAME}"

    # 生成基础 frps.ini 配置文件
    cat > ${WORK_DIR}/frps.ini << F_EOF
[common]
bind_port = ${BIND_PORT}
token = ${FRP_TOKEN}
tcp_mux = true
F_EOF
    echo "[完成] 生成配置文件：${WORK_DIR}/frps.ini"
    cat ${WORK_DIR}/frps.ini
    echo "---------------------------------------------"

    # 使用私有高速镜像下载
    cd ${WORK_DIR} || exit 1
    MY_MIRROR_URL="https://ipan.mbvpn.cn/mstsc/${ZIP_NAME}"
    
    echo "[下载] 正在从私有高速镜像站下载: ${MY_MIRROR_URL}"
    if command -v wget &> /dev/null; then
        wget -c --timeout=30 --tries=3 "${MY_MIRROR_URL}"
    else
        curl -fL --connect-timeout 15 --max-time 300 -o "${ZIP_NAME}" "${MY_MIRROR_URL}"
    fi

    # 完整性校验
    if [ ! -f "${ZIP_NAME}" ] || ! tar -tzf "${ZIP_NAME}" &> /dev/null; then
        echo "[错误] 镜像包下载失败或文件已损坏！"
        exit 1
    fi

    # 解压与提取
    tar -zxf ${ZIP_NAME}
    mv frp_${VER_NUM}_linux_${FRP_ARCH}/frps ${WORK_DIR}/frps
    chmod +x ${WORK_DIR}/frps
    rm -rf frp_${VER_NUM}_linux_${FRP_ARCH} ${ZIP_NAME}

    # 防火墙初始放行 7000 端口
    open_port_firewall ${BIND_PORT}

    # 创建 systemd
    cat > /etc/systemd/system/frps.service << S_EOF
[Unit]
Description=FRP Server Service
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
ExecStart=${WORK_DIR}/frps -c ${WORK_DIR}/frps.ini
Restart=always
RestartSec=5
StandardOutput=journal+console

[Install]
WantedBy=multi-user.target
S_EOF

    echo "[完成] 生成并配置 frps.service 系统服务"
    systemctl daemon-reload
    systemctl enable frps >/dev/null 2>&1
    
    # 启动服务
    systemctl restart frps

    # 如果数据库里有历史端口，批量重新放行防火墙
    if [ -s "$PORT_DB" ]; then
        echo "[系统] 正在为历史配置的端口重新应用防火墙规则..."
        for line in $(cat "$PORT_DB"); do
            port=$(echo "$line" | cut -d"|" -f1)
            open_port_firewall "$port"
        done
    else
        # 默认加一个 8899 作为初始端口
        echo "8899|Default_Friend" > "$PORT_DB"
        open_port_firewall 8899
    fi

    echo "============================================="
    echo " FRPS 部署成功！"
    echo "============================================="
    read -p "按回车键返回主菜单..." temp
}

# ------------------------------------------------------------
#  2. 防火墙底边指令
# ------------------------------------------------------------
open_port_firewall() {
    local port=$1
    if command -v firewall-cmd &> /dev/null; then
        firewall-cmd --add-port=${port}/tcp --permanent >/dev/null 2>&1
        firewall-cmd --reload >/dev/null 2>&1
    elif command -v ufw &> /dev/null; then
        ufw allow ${port}/tcp >/dev/null 2>&1
    fi
}

close_port_firewall() {
    local port=$1
    if command -v firewall-cmd &> /dev/null; then
        firewall-cmd --remove-port=${port}/tcp --permanent >/dev/null 2>&1
        firewall-cmd --reload >/dev/null 2>&1
    elif command -v ufw &> /dev/null; then
        ufw delete allow ${port}/tcp >/dev/null 2>&1
    fi
}

# ------------------------------------------------------------
#  3. 二级菜单：端口管理面板
# ------------------------------------------------------------
port_management_menu() {
    while true; do
        clear
        echo "============================================="
        echo "       FRPS 端口管理面板 (二级菜单)"
        echo "============================================="
        echo -e " \e[1m端口号\e[0m\t\t|\e[1m 使用者/备注描述\e[0m"
        echo "---------------------------------------------"
        if [ ! -s "$PORT_DB" ]; then
            echo " [提示] 暂无已分配的自定义端口。"
        else
            for line in $(cat "$PORT_DB"); do
                port=$(echo "$line" | cut -d"|" -f1)
                user=$(echo "$line" | cut -d"|" -f2)
                echo -e "  \e[36m${port}\e[0m\t\t|  ${user}"
            done
        fi
        echo "---------------------------------------------"
        echo " 核心控制端口: ${BIND_PORT} (已放行)"
        echo "============================================="
        echo "  [1] 新增端口映射（自动放行防火墙）"
        echo "  [2] 删除端口映射（自动关闭防火墙）"
        echo "  [0] 返回主菜单"
        echo "============================================="
        read -p "请选择操作 [0-2]: " port_choice

        case "$port_choice" in
            1)
                echo ""
                read -p "请输入要新增的远程端口 (例如 8900): " new_port
                if ! [[ "$new_port" =~ ^[0-9]+$ ]] || [ "$new_port" -le 1024 ] || [ "$new_port" -ge 65535 ]; then
                    echo -e "\e[31m[错误] 输入无效，请输入 1025-65534 之间的数字端口！\e[0m"
                    sleep 2
                    continue
                fi

                if grep -q "^${new_port}|" "$PORT_DB"; then
                    echo -e "\e[31m[错误] 端口 ${new_port} 已被占用！\e[0m"
                    sleep 2
                    continue
                fi

                read -p "请输入使用者名字或设备备注 (例如 Friend_A): " user_name
                if [ -z "$user_name" ]; then
                    user_name="Unnamed_User"
                fi

                echo "${new_port}|${user_name}" >> "$PORT_DB"
                open_port_firewall "$new_port"
                echo -e "\e[32m[成功] 端口 ${new_port} (${user_name}) 已成功开放并加入防火墙白名单！\e[0m"
                sleep 2
                ;;
            2)
                echo ""
                read -p "请输入要删除/收回的端口号: " del_port
                if ! grep -q "^${del_port}|" "$PORT_DB"; then
                    echo -e "\e[31m[错误] 未找到端口 ${del_port} 的分配记录！\e[0m"
                    sleep 2
                    continue
                fi

                sed -i "/^${del_port}|/d" "$PORT_DB"
                close_port_firewall "$del_port"
                echo -e "\e[32m[成功] 端口 ${del_port} 已被注销，防火墙规则已收回！\e[0m"
                sleep 2
                ;;
            0)
                return
                ;;
            *)
                echo -e "\e[31m无效的选择，请重新输入！\e[0m"
                sleep 1
                ;;
        esac
    done
}

# ------------------------------------------------------------
#  4. 卸载逻辑
# ------------------------------------------------------------
uninstall_frps() {
    echo ""
    read -p "⚠️ 确定要完全卸载 FRPS 服务并清理所有数据吗？(y/n): " confirm
    if [ "$confirm" != "y" ] && [ "$confirm" != "Y" ]; then
        echo "已取消卸载。"
        sleep 1
        return
    fi

    echo "[1/4] 正在停止并禁用 frps 服务..."
    systemctl stop frps >/dev/null 2>&1
    systemctl disable frps >/dev/null 2>&1
    rm -f /etc/systemd/system/frps.service
    systemctl daemon-reload

    echo "[2/4] 正在清除防火墙放行规则..."
    close_port_firewall ${BIND_PORT}
    if [ -f "$PORT_DB" ]; then
        for line in $(cat "$PORT_DB"); do
            port=$(echo "$line" | cut -d"|" -f1)
            close_port_firewall "$port"
        done
    fi

    echo "[3/4] 正在删除程序文件与配置数据库..."
    rm -f ${WORK_DIR}/frps
    rm -f ${WORK_DIR}/frps.ini
    rm -f "$PORT_DB"

    echo "[4/4] 清理所有残留进程..."
    cleanup_ghost_processes

    echo "============================================="
    echo "  FRPS 服务已完全卸载，所有端口规则已收回！"
    echo "============================================="
    read -p "按回车键退出程序..." temp
    exit 0
}

# ------------------------------------------------------------
#  主菜单循环
# ------------------------------------------------------------
while true; do
    clear
    echo "============================================="
    echo "         FRPS 简易交互式管理器"
    echo "============================================="
    echo " 服务运行状态: $(get_status)"
    echo " 核心控制端口: ${BIND_PORT}"
    echo "---------------------------------------------"
    echo "  [1] 安装 / 重建 FRPS 环境"
    echo "  [2] 端口管理面板 (查看/新增/删除)"
    echo "  [3] 彻底卸载 FRPS 服务"
    echo "  [0] 退出管理面板"
    echo "============================================="
    read -p "请输入操作编号 [0-3]: " menu_choice

    case "$menu_choice" in
        1)
            install_frps
            ;;
        2)
            port_management_menu
            ;;
        3)
            uninstall_frps
            ;;
        0)
            echo "感谢使用，再见！"
            exit 0
            ;;
        *)
            echo -e "\e[31m无效的选择，请重新输入！\e[0m"
            sleep 1
            ;;
    esac
done
