#!/bin/bash

# 获取当前网络接口名称
get_interface() {
    # 多种方式获取活动接口
    local interface
    interface=$(ip route get 1.1.1.1 2>/dev/null | awk '{for(i=1;i<=NF;i++) if($i=="dev") print $(i+1)}')
    
    if [ -z "$interface" ]; then
        interface=$(ip route show default 2>/dev/null | awk '{for(i=1;i<=NF;i++) if($i=="dev") print $(i+1)}' | head -n1)
    fi
    
    if [ -z "$interface" ]; then
        interface=$(ls /sys/class/net | grep -E '^(en|eth|wlan|wlp)' | head -n1)
    fi
    
    if [ -z "$interface" ]; then
        interface=$(ls /sys/class/net | grep -Ev '^(lo|docker|veth|vmnet|br-|virbr)' | head -n1)
    fi
    
    echo "$interface"
}

INTERFACE=$(get_interface)

# 获取当前IP和网关信息
get_current_ip() {
    ip -4 addr show "$INTERFACE" 2>/dev/null | grep -oP '(?<=inet\s)\d+(\.\d+){3}' | head -n1
}

get_current_gateway() {
    ip route show default 2>/dev/null | grep -oP '(?<=via\s)\d+(\.\d+){3}' | head -n1
}

get_current_forward() {
    cat /proc/sys/net/ipv4/ip_forward 2>/dev/null || echo "0"
}

CURRENT_IP=$(get_current_ip)
CURRENT_GATEWAY=$(get_current_gateway)
CURRENT_FORWARD=$(get_current_forward)

# 获取当前DNS配置
get_current_dns() {
    if command -v resolvectl >/dev/null 2>&1; then
        resolvectl status 2>/dev/null | grep 'DNS Servers' | awk '{for(i=3;i<=NF;i++) printf "%s ", $i}' | sed 's/ $//'
    elif [ -f /etc/resolv.conf ]; then
        grep -E '^nameserver' /etc/resolv.conf | awk '{print $2}' | tr '\n' ' ' | sed 's/ $//'
    else
        echo "无法获取DNS信息"
    fi
}

CURRENT_DNS=$(get_current_dns)

function detect_network_manager() {
    if command -v nmcli >/dev/null 2>&1 && (systemctl is-active NetworkManager >/dev/null 2>&1 || pgrep NetworkManager >/dev/null); then
        echo "NetworkManager"
    elif systemctl is-active systemd-networkd >/dev/null 2>&1; then
        echo "systemd-networkd"
    elif [ -f /etc/network/interfaces ] && command -v ifup >/dev/null 2>&1; then
        echo "ifupdown"
    elif [ -f /etc/sysconfig/network-scripts/ifcfg-* ] 2>/dev/null; then
        echo "redhat-sysconfig"
    elif command -v netplan >/dev/null 2>&1; then
        echo "netplan"
    else
        echo "unknown"
    fi
}

NETWORK_MANAGER=$(detect_network_manager)

# 保存网络配置到配置文件
function save_network_config() {
    local ip="$1"
    local gateway="$2"
    
    case "$NETWORK_MANAGER" in
        NetworkManager)
            if command -v nmcli >/dev/null 2>&1; then
                local conn_name
                conn_name=$(nmcli -t -f NAME,DEVICE connection show | grep ":${INTERFACE}$" | cut -d: -f1 | head -n1)
                if [ -n "$conn_name" ] && [ -n "$ip" ]; then
                    # 设置IP地址和网关
                    nmcli connection modify "$conn_name" ipv4.method manual
                    nmcli connection modify "$conn_name" ipv4.addresses "${ip}/24"
                    if [ -n "$gateway" ]; then
                        nmcli connection modify "$conn_name" ipv4.gateway "$gateway"
                    fi
                    echo "NetworkManager配置已更新"
                fi
            fi
            ;;
        systemd-networkd)
            local network_file="/etc/systemd/network/$(ls /etc/systemd/network/ | grep -E "\.network$" | head -n1)"
            if [ -f "$network_file" ] && [ -n "$ip" ]; then
                # 备份原文件
                cp "$network_file" "${network_file}.backup"
                # 更新配置
                sed -i '/^Address=/d;/^Gateway=/d' "$network_file"
                echo "Address=${ip}/24" >> "$network_file"
                if [ -n "$gateway" ]; then
                    echo "Gateway=$gateway" >> "$network_file"
                fi
                echo "systemd-networkd配置已更新"
            fi
            ;;
        ifupdown)
            if [ -f /etc/network/interfaces ] && [ -n "$ip" ]; then
                # 备份原文件
                cp /etc/network/interfaces /etc/network/interfaces.backup
                # 更新配置
                if grep -q "iface $INTERFACE inet" /etc/network/interfaces; then
                    sed -i "/iface $INTERFACE inet/,/^$/ {/address/d;/gateway/d}" /etc/network/interfaces
                    sed -i "/iface $INTERFACE inet/ a\    address $ip/24" /etc/network/interfaces
                    if [ -n "$gateway" ]; then
                        sed -i "/iface $INTERFACE inet/ a\    gateway $gateway" /etc/network/interfaces
                    fi
                else
                    echo "" >> /etc/network/interfaces
                    echo "auto $INTERFACE" >> /etc/network/interfaces
                    echo "iface $INTERFACE inet static" >> /etc/network/interfaces
                    echo "    address $ip/24" >> /etc/network/interfaces
                    if [ -n "$gateway" ]; then
                        echo "    gateway $gateway" >> /etc/network/interfaces
                    fi
                fi
                echo "ifupdown配置已更新"
            fi
            ;;
        *)
            echo "警告: 未知的网络管理器，配置可能无法永久保存"
            ;;
    esac
}

function restart_network() {
    case "$NETWORK_MANAGER" in
        NetworkManager)
            if command -v nmcli >/dev/null 2>&1; then
                nmcli connection reload 2>/dev/null
                nmcli device disconnect "$INTERFACE" 2>/dev/null
                sleep 2
                nmcli device connect "$INTERFACE" 2>/dev/null
            fi
            ;;
        systemd-networkd)
            systemctl restart systemd-networkd 2>/dev/null
            ;;
        ifupdown)
            if command -v ifdown >/dev/null 2>&1 && command -v ifup >/dev/null 2>&1; then
                ifdown "$INTERFACE" 2>/dev/null && ifup "$INTERFACE" 2>/dev/null
            fi
            ;;
        redhat-sysconfig)
            systemctl restart network 2>/dev/null
            ;;
        netplan)
            netplan apply 2>/dev/null
            ;;
        *)
            echo "无法识别的网络管理器，请手动重启网络服务。"
            return 1
            ;;
    esac
    echo "网络已重启。"
}

function set_dns() {
    local dns_servers="$1"
    
    case "$NETWORK_MANAGER" in
        NetworkManager)
            if command -v nmcli >/dev/null 2>&1; then
                local conn_name
                conn_name=$(nmcli -t -f NAME,DEVICE connection show | grep ":${INTERFACE}$" | cut -d: -f1 | head -n1)
                if [ -n "$conn_name" ]; then
                    nmcli connection modify "$conn_name" ipv4.dns "$dns_servers"
                    nmcli connection modify "$conn_name" ipv4.ignore-auto-dns yes
                    echo "DNS已设置为: $dns_servers (NetworkManager)"
                fi
            fi
            ;;
        systemd-networkd)
            local network_file="/etc/systemd/network/$(ls /etc/systemd/network/ | grep -E "\.network$" | head -n1)"
            if [ -f "$network_file" ]; then
                sed -i '/^DNS=/d' "$network_file"
                echo "DNS=$dns_servers" >> "$network_file"
                echo "DNS已设置为: $dns_servers (systemd-networkd)"
            else
                echo "未找到systemd-networkd配置文件"
            fi
            ;;
        ifupdown)
            if [ -f /etc/resolv.conf ]; then
                cp /etc/resolv.conf /etc/resolv.conf.backup
                echo "# Generated by network script" > /etc/resolv.conf
                for server in $dns_servers; do
                    echo "nameserver $server" >> /etc/resolv.conf
                done
                echo "DNS已设置为: $dns_servers (ifupdown)"
            fi
            ;;
        *)
            # 通用方法
            if [ -f /etc/resolv.conf ]; then
                cp /etc/resolv.conf /etc/resolv.conf.backup
                echo "# Generated by network script" > /etc/resolv.conf
                for server in $dns_servers; do
                    echo "nameserver $server" >> /etc/resolv.conf
                done
                echo "DNS已设置为: $dns_servers (通用方法)"
            else
                echo "无法设置DNS: 未知的网络管理器"
                return 1
            fi
            ;;
    esac
    
    # 更新当前DNS变量
    CURRENT_DNS=$dns_servers
    return 0
}

function print_menu() {
    clear
    echo "========================================"
    echo "          网络设置管理菜单"
    echo "========================================"
    echo "网络管理器: $NETWORK_MANAGER"
    echo "接口: $INTERFACE"
    echo "----------------------------------------"
    echo "1. 查看当前状态"
    echo "2. 修改IP地址"
    echo "3. 修改网关"
    echo "4. 修改DNS服务器"
    echo "5. 启用全局流量转发"
    echo "6. 启用指定地址的流量转发"
    echo "7. 恢复默认配置"
    echo "8. 保存并重启网络"
    echo "9. 测试网络连接"
    echo "0. 退出"
    echo "========================================"
}

function current_status() {
    echo "当前网络状态:"
    echo "----------------------------------------"
    echo "IP 地址: ${CURRENT_IP:-未获取}"
    echo "网关: ${CURRENT_GATEWAY:-未获取}"
    echo "DNS: ${CURRENT_DNS:-未获取}"
    echo "流量转发: $([ "$CURRENT_FORWARD" -eq 1 ] && echo "启用" || echo "禁用")"
    echo "网络接口: $INTERFACE"
    echo "网络管理器: $NETWORK_MANAGER"
    echo "----------------------------------------"
}

function modify_ip() {
    read -p "请输入新的IP地址 (例如: 192.168.1.100): " new_ip
    if [[ "$new_ip" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then
        CURRENT_IP=$new_ip
        echo "新的IP地址已暂时设置: $CURRENT_IP"
    else
        echo "无效的IP地址格式，请重新输入。"
    fi
}

function modify_gateway() {
    read -p "请输入新的网关地址 (例如: 192.168.1.1): " new_gateway
    if [[ "$new_gateway" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then
        CURRENT_GATEWAY=$new_gateway
        echo "新的网关已暂时设置: $CURRENT_GATEWAY"
    else
        echo "无效的网关格式，请重新输入。"
    fi
}

function modify_dns() {
    read -p "请输入DNS服务器地址 (多个用空格分隔，例如: 8.8.8.8 1.1.1.1): " new_dns
    # 验证DNS地址格式
    local valid=true
    for dns in $new_dns; do
        if ! [[ "$dns" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then
            echo "无效的DNS地址: $dns"
            valid=false
            break
        fi
    done
    
    if [ "$valid" = true ] && [ -n "$new_dns" ]; then
        if set_dns "$new_dns"; then
            echo "DNS已设置为: $new_dns"
        else
            echo "DNS设置失败"
        fi
    else
        echo "DNS设置无效"
    fi
}

function enable_global_forwarding() {
    read -p "确认要启用全局流量转发吗？（y/n）: " confirm
    if [ "$confirm" = "y" ] || [ "$confirm" = "Y" ]; then
        sysctl -w net.ipv4.ip_forward=1 2>/dev/null
        echo 'net.ipv4.ip_forward=1' > /etc/sysctl.d/99-ipforward.conf 2>/dev/null
        CURRENT_FORWARD=1
        echo "已启用全局流量转发。"
    else
        echo "取消启用全局流量转发。"
    fi
}

function enable_specific_forwarding() {
    read -p "请输入源地址 (例如: 192.168.2.0/24): " source_ip
    read -p "请输入目标网关地址: " gateway
    
    if command -v iptables >/dev/null 2>&1; then
        iptables -t nat -A POSTROUTING -s "$source_ip" -j MASQUERADE 2>/dev/null
        ip rule add from "$source_ip" table 100 2>/dev/null
        ip route add default via "$gateway" dev "$INTERFACE" table 100 2>/dev/null
        echo "已启用指定地址的流量转发。"
    else
        echo "iptables未安装，无法启用流量转发。"
    fi
}

function restore_default_config() {
    read -p "确认要恢复默认配置吗？（y/n）: " confirm
    if [ "$confirm" = "y" ] || [ "$confirm" = "Y" ]; then
        # 重置网络配置
        ip addr flush dev "$INTERFACE" 2>/dev/null
        if [ -n "$CURRENT_IP" ]; then
            ip addr add "${CURRENT_IP}/24" dev "$INTERFACE" 2>/dev/null
        fi
        if [ -n "$CURRENT_GATEWAY" ]; then
            ip route add default via "$CURRENT_GATEWAY" dev "$INTERFACE" 2>/dev/null
        fi
        sysctl -w net.ipv4.ip_forward=0 2>/dev/null
        CURRENT_FORWARD=0
        echo "已恢复默认配置。"
    else
        echo "取消恢复默认配置。"
    fi
}

function test_network() {
    echo "测试网络连接..."
    echo "----------------------------------------"
    
    # 测试本地连接
    echo "1. 测试本地网络接口:"
    ip link show "$INTERFACE" 2>/dev/null | grep -E "state|mtu"
    
    echo -e "\n2. 测试DNS解析:"
    if ping -c 2 -W 1 google.com >/dev/null 2>&1; then
        echo "DNS解析: 正常"
    elif ping -c 2 -W 1 8.8.8.8 >/dev/null 2>&1; then
        echo "DNS解析: 失败，但网络可达"
    else
        echo "DNS解析: 失败，网络不可达"
    fi
    
    echo -e "\n3. 测试互联网连接:"
    if ping -c 2 -W 1 1.1.1.1 >/dev/null 2>&1; then
        echo "互联网连接: 正常"
    else
        echo "互联网连接: 失败"
    fi
    
    echo "----------------------------------------"
}

function apply_changes() {
    echo "应用更改..."
    
    # 保存配置到文件（永久生效）
    save_network_config "$CURRENT_IP" "$CURRENT_GATEWAY"
    
    # 设置临时IP地址和网关
    if [ -n "$CURRENT_IP" ]; then
        ip addr flush dev "$INTERFACE" 2>/dev/null
        ip addr add "${CURRENT_IP}/24" dev "$INTERFACE" 2>/dev/null
    fi
    
    # 设置网关
    if [ -n "$CURRENT_GATEWAY" ]; then
        # 删除所有默认路由
        ip route del default 2>/dev/null
        # 添加新的默认路由
        ip route add default via "$CURRENT_GATEWAY" dev "$INTERFACE" 2>/dev/null
        echo "网关已设置为: $CURRENT_GATEWAY"
    fi
    
    # 重启网络服务
    if restart_network; then
        echo "更改已保存并网络重启成功。"
        
        # 验证网关设置
        local new_gateway=$(get_current_gateway)
        if [ "$new_gateway" = "$CURRENT_GATEWAY" ]; then
            echo "网关设置验证成功: $new_gateway"
        else
            echo "警告: 网关设置可能未生效，当前网关: ${new_gateway:-无}"
        fi
    else
        echo "更改已保存，但网络重启可能失败，请检查。"
    fi
    
    # 更新状态信息
    CURRENT_IP=$(get_current_ip)
    CURRENT_GATEWAY=$(get_current_gateway)
    CURRENT_DNS=$(get_current_dns)
}

function main_menu() {
    while true; do
        print_menu
        read -rp "请选择操作 (0-9): " choice

        case $choice in
            1) current_status ;;
            2) modify_ip ;;
            3) modify_gateway ;;
            4) modify_dns ;;
            5) enable_global_forwarding ;;
            6) enable_specific_forwarding ;;
            7) restore_default_config ;;
            8) apply_changes ;;
            9) test_network ;;
            0) 
                echo "退出网络设置管理。"
                exit 0 
                ;;
            *) 
                echo "无效的选择，请重新输入。"
                sleep 1
                ;;
        esac

        if [ "$choice" -ne 0 ]; then
            read -rp "按回车键继续... " 
        fi
    done
}

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

# 检查必要的命令
if ! command -v ip >/dev/null 2>&1; then
    echo "错误: ip 命令未找到，请安装 iproute2 包。"
    exit 1
fi

main_menu