#!/bin/bash
# Author: Ropon Lilaihu (Modified)
# Blog: https://www.ropon.top https://www.lnmpweb.cn

# 全局变量
restartflag=0
OS=""
OSVer=""
NET_INTERFACE=""
NET_CONFIG_DIR=""
NET_CONFIG_FILE=""
RESOLV_CONF="/etc/resolv.conf"
IPV4_ADDR=""
IPV4_GATEWAY=""
IPV6_GATEWAY=""

# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# 帮助信息
Help() {
    echo -e "${GREEN}Usage:${NC} ./$(basename $0) [OPTIONS] [IPV6_ADDRESS...]"
    echo
    echo -e "${GREEN}OPTIONS:${NC}"
    echo "  -i | --info         : 显示网卡信息和当前IPv6配置"
    echo "  -s | --single       : 绑定单个IPv6地址"
    echo "  -b | --batch        : 批量绑定IPv6地址（范围）"
    echo "  -h | --help         : 显示帮助信息"
    echo
    echo -e "${GREEN}Examples:${NC}"
    echo "  ./$(basename $0) -i"
    echo "  ./$(basename $0) -s 240e:d9:c200:101:7bb2::120"
    echo "  ./$(basename $0) -b 240e:d9:c200:101:7bb2::120 240e:d9:c200:101:7bb2::130"
    echo
}

# 检测操作系统
CheckOS() {
    if [ -f /etc/os-release ]; then
        . /etc/os-release
        OS=$ID
        OSVer=$VERSION_ID
    elif [ -f /etc/redhat-release ]; then
        OS="centos"
        OSVer=$(grep -oE '[0-9]+\.[0-9]+' /etc/redhat-release | head -1)
    elif [ -f /etc/debian_version ]; then
        OS="debian"
        OSVer=$(cat /etc/debian_version)
    else
        OS="unknown"
        OSVer="unknown"
    fi
    
    # 统一版本号格式
    OSVer=$(echo $OSVer | cut -d. -f1)
    
    # 检测网卡
    DetectNetworkInterface
}

# 检测网卡接口
DetectNetworkInterface() {
    # 获取第一个有IPv4地址的网卡（排除lo）
    NET_INTERFACE=$(ip -4 addr show | grep -v lo | grep -E '^[0-9]+:' | head -1 | awk -F': ' '{print $2}')
    
    if [ -z "$NET_INTERFACE" ]; then
        # 如果没找到有IPv4的网卡，获取第一个非lo网卡
        NET_INTERFACE=$(ip link show | grep -E '^[0-9]+:' | grep -v lo | head -1 | awk -F': ' '{print $2}')
    fi
    
    if [ -z "$NET_INTERFACE" ]; then
        echo -e "${RED}Error: No network interface found${NC}"
        exit 1
    fi
    
    # 获取IPv4地址和网关
    GetNetworkInfo
    
    # 设置网络配置文件路径
    SetConfigPath
}

# 获取网络信息
GetNetworkInfo() {
    # 获取IPv4地址
    IPV4_ADDR=$(ip -4 addr show $NET_INTERFACE | grep inet | head -1 | awk '{print $2}')
    
    # 获取IPv4网关
    IPV4_GATEWAY=$(ip -4 route show default | grep $NET_INTERFACE | awk '{print $3}')
    if [ -z "$IPV4_GATEWAY" ]; then
        IPV4_GATEWAY=$(ip -4 route show | grep $NET_INTERFACE | grep -v default | grep -v kernel | awk '{print $1}' | head -1)
    fi
    
    # 获取IPv6网关
    IPV6_GATEWAY=$(ip -6 route show default | grep $NET_INTERFACE | awk '{print $3}')
    if [ -z "$IPV6_GATEWAY" ]; then
        # 如果默认网关不存在，尝试从已有IPv6地址生成
        local ipv6_addr=$(ip -6 addr show $NET_INTERFACE | grep -v fe80 | grep inet6 | head -1 | awk '{print $2}' | cut -d/ -f1)
        if [ -n "$ipv6_addr" ]; then
            IPV6_GATEWAY=$(echo $ipv6_addr | awk -F ':' '{print $1":"$2":"$3":"$4"::1"}')
        fi
    fi
}

# 设置配置文件路径
SetConfigPath() {
    if [[ "$OS" == "centos" || "$OS" == "rhel" || "$OS" == "fedora" ]]; then
        NET_CONFIG_DIR="/etc/sysconfig/network-scripts"
        NET_CONFIG_FILE="$NET_CONFIG_DIR/ifcfg-$NET_INTERFACE"
    elif [[ "$OS" == "debian" ]]; then
        NET_CONFIG_DIR="/etc/network"
        NET_CONFIG_FILE="$NET_CONFIG_DIR/interfaces"
    elif [[ "$OS" == "ubuntu" ]]; then
        if [[ "$OSVer" -ge 20 ]]; then
            NET_CONFIG_DIR="/etc/netplan"
            # 查找现有的netplan配置文件
            if [ -f "$NET_CONFIG_DIR/50-cloud-init.yaml" ]; then
                NET_CONFIG_FILE="$NET_CONFIG_DIR/50-cloud-init.yaml"
            elif [ -f "$NET_CONFIG_DIR/00-installer-config.yaml" ]; then
                NET_CONFIG_FILE="$NET_CONFIG_DIR/00-installer-config.yaml"
            elif [ -f "$NET_CONFIG_DIR/01-netcfg.yaml" ]; then
                NET_CONFIG_FILE="$NET_CONFIG_DIR/01-netcfg.yaml"
            else
                # 创建新的配置文件
                NET_CONFIG_FILE="$NET_CONFIG_DIR/01-netcfg.yaml"
            fi
        else
            NET_CONFIG_DIR="/etc/network"
            NET_CONFIG_FILE="$NET_CONFIG_DIR/interfaces"
        fi
    else
        echo -e "${RED}Unsupported OS: $OS${NC}"
        exit 1
    fi
}

# 显示网卡信息和IPv6配置
ShowNetworkInfo() {
    echo -e "${GREEN}========================================${NC}"
    echo -e "${GREEN}Network Interface Information${NC}"
    echo -e "${GREEN}========================================${NC}"
    echo -e "${YELLOW}OS:${NC} $OS $OSVer"
    echo -e "${YELLOW}Network Interface:${NC} $NET_INTERFACE"
    echo -e "${YELLOW}Config File:${NC} $NET_CONFIG_FILE"
    echo
    echo -e "${GREEN}--- IPv4 Information ---${NC}"
    echo -e "${YELLOW}  Address:${NC} ${IPV4_ADDR:-N/A}"
    echo -e "${YELLOW}  Gateway:${NC} ${IPV4_GATEWAY:-N/A}"
    echo
    echo -e "${GREEN}--- IPv6 Information ---${NC}"
    echo -e "${YELLOW}  Addresses:${NC}"
    ip -6 addr show $NET_INTERFACE | grep -v fe80 | grep inet6 | awk '{print "    " $2}'
    echo -e "${YELLOW}  Gateway:${NC} ${IPV6_GATEWAY:-N/A}"
    echo
    echo -e "${GREEN}--- IPv6 DNS ---${NC}"
    if [ -f "$RESOLV_CONF" ]; then
        grep -E '^nameserver.*:' $RESOLV_CONF 2>/dev/null | awk '{print "  " $2}' || echo "  No IPv6 DNS configured"
    fi
    echo
    echo -e "${GREEN}--- Current IPv6 Routes ---${NC}"
    ip -6 route show dev $NET_INTERFACE | grep -v fe80 | awk '{print "  " $0}'
    echo
    echo -e "${GREEN}========================================${NC}"
}

# 获取IPv6网关（从IP地址自动生成）
GetIPv6Gateway() {
    local ipv6=$1
    if [ -n "$ipv6" ]; then
        echo $ipv6 | awk -F ':' '{print $1":"$2":"$3":"$4"::1"}'
    else
        echo ""
    fi
}

# CentOS 单IP配置
SetupCentOS() {
    local ipv6=$1
    local ipgw=$(GetIPv6Gateway "$ipv6")
    local dns_servers="nameserver 240C::6666\nnameserver 2001:4860:4860::8888"
    
    [ -f $NET_CONFIG_FILE ] && cp $NET_CONFIG_FILE ${NET_CONFIG_FILE}.bak
    
    # 检查是否已配置IPv6
    if ! grep -q '^IPV6INIT=yes' $NET_CONFIG_FILE 2>/dev/null; then
        # 添加IPv6配置
        cat >> $NET_CONFIG_FILE << EOF

# IPv6 Configuration
IPV6INIT=yes
IPV6_DEFROUTE=yes
IPV6ADDR=${ipv6}/64
IPV6_DEFAULTGW=$ipgw
EOF
        restartflag=1
    else
        # 如果已存在，检查是否已有IPV6ADDR配置
        if grep -q '^IPV6ADDR=' $NET_CONFIG_FILE 2>/dev/null; then
            # 检查是否已存在相同的IP
            if grep -q "IPV6ADDR=${ipv6}/64" $NET_CONFIG_FILE 2>/dev/null; then
                echo -e "${YELLOW}IPv6 address $ipv6 already exists${NC}"
            else
                # 添加为第二个地址（使用IPV6ADDR_SECONDARIES）
                if grep -q '^IPV6ADDR_SECONDARIES=' $NET_CONFIG_FILE 2>/dev/null; then
                    # 如果已有SECONDARIES，追加
                    sed -i "/^IPV6ADDR_SECONDARIES=/ s/\"$/ ${ipv6}\/64\"/" $NET_CONFIG_FILE
                else
                    echo "IPV6ADDR_SECONDARIES=\"${ipv6}/64\"" >> $NET_CONFIG_FILE
                fi
                restartflag=1
            fi
        else
            # 添加新的IPV6ADDR
            sed -i "/^IPV6INIT=yes/a IPV6ADDR=${ipv6}/64" $NET_CONFIG_FILE
            sed -i "/^IPV6INIT=yes/a IPV6_DEFAULTGW=$ipgw" $NET_CONFIG_FILE
            restartflag=1
        fi
    fi
    
    # 配置DNS
    if ! grep -q '^nameserver .*:' $RESOLV_CONF 2>/dev/null; then
        echo -e "$dns_servers" >> $RESOLV_CONF
        restartflag=1
    fi
    
    # 重启网络服务
    if [ $restartflag -eq 1 ]; then
        systemctl restart network 2>/dev/null || service network restart 2>/dev/null
        echo -e "${GREEN}IPv6 configuration updated successfully${NC}"
        echo -e "${GREEN}Added IPv6: ${ipv6}/64${NC}"
    else
        echo -e "${YELLOW}No changes needed${NC}"
    fi
}

# CentOS 批量绑定
BatchCentOS() {
    local start=$1
    local end=$2
    local start_num=$(printf %d 0X${start##*:} 2>/dev/null)
    local end_num=$(printf %d 0X${end##*:} 2>/dev/null)
    
    if [ -z "$start_num" ] || [ -z "$end_num" ]; then
        echo -e "${RED}Error: Invalid IPv6 address format${NC}"
        exit 1
    fi
    
    local prefix=${start%:*}
    local total=$((end_num - start_num + 1))
    
    if [ $total -le 0 ]; then
        echo -e "${RED}Error: End address must be greater than start address${NC}"
        exit 1
    fi
    
    [ -f $NET_CONFIG_FILE ] && cp $NET_CONFIG_FILE ${NET_CONFIG_FILE}.bak
    
    # 确保IPv6已启用
    if ! grep -q '^IPV6INIT=yes' $NET_CONFIG_FILE 2>/dev/null; then
        local ipgw=$(GetIPv6Gateway "$start")
        cat >> $NET_CONFIG_FILE << EOF

# IPv6 Configuration
IPV6INIT=yes
IPV6_DEFROUTE=yes
IPV6_DEFAULTGW=$ipgw
EOF
    fi
    
    # 构建IP列表
    local ip_list=""
    local current_num=$start_num
    for ((i=1; i<=$total; i++)); do
        local current=$(printf "%x" $current_num)
        if [ -n "$ip_list" ]; then
            ip_list="$ip_list ${prefix}:${current}/64"
        else
            ip_list="${prefix}:${current}/64"
        fi
        current_num=$((current_num + 1))
    done
    
    # 检查是否已有IPV6ADDR_SECONDARIES
    if grep -q '^IPV6ADDR_SECONDARIES=' $NET_CONFIG_FILE 2>/dev/null; then
        # 获取现有IP列表
        local existing=$(grep '^IPV6ADDR_SECONDARIES=' $NET_CONFIG_FILE | cut -d= -f2 | tr -d '"')
        # 合并IP列表
        local merged="$existing $ip_list"
        # 更新配置
        sed -i "/^IPV6ADDR_SECONDARIES=/c IPV6ADDR_SECONDARIES=\"$merged\"" $NET_CONFIG_FILE
    else
        echo "IPV6ADDR_SECONDARIES=\"$ip_list\"" >> $NET_CONFIG_FILE
    fi
    
    restartflag=1
    
    # 重启网络
    if [ $restartflag -eq 1 ]; then
        systemctl restart network 2>/dev/null || service network restart 2>/dev/null
        echo -e "${GREEN}Batch IPv6 binding completed${NC}"
        echo -e "${GREEN}Added $total IPv6 addresses${NC}"
        echo -e "${YELLOW}IP Range:${NC} $start - $end"
    fi
}

# Debian 网络配置
SetupDebian() {
    local ipv6=$1
    local ipgw=$(GetIPv6Gateway "$ipv6")
    local dns_servers="dns-nameservers 240C::6666 2001:4860:4860::8888"
    
    [ -f $NET_CONFIG_FILE ] && cp $NET_CONFIG_FILE ${NET_CONFIG_FILE}.bak
    
    # 检查是否已存在该网卡的IPv6配置
    if grep -q "iface $NET_INTERFACE inet6 static" $NET_CONFIG_FILE 2>/dev/null; then
        # 检查是否已存在该IP
        if grep -q "address ${ipv6}/64" $NET_CONFIG_FILE 2>/dev/null; then
            echo -e "${YELLOW}IPv6 address $ipv6 already exists${NC}"
        else
            # 在配置段中添加新地址
            sed -i "/iface $NET_INTERFACE inet6 static/a\    address ${ipv6}/64" $NET_CONFIG_FILE
            restartflag=1
        fi
    else
        # 创建新的IPv6配置段
        cat >> $NET_CONFIG_FILE << EOF

# IPv6 Configuration
iface $NET_INTERFACE inet6 static
    address ${ipv6}/64
    gateway $ipgw
    $dns_servers
EOF
        restartflag=1
    fi
    
    # 重启网络
    if [ $restartflag -eq 1 ]; then
        systemctl restart networking 2>/dev/null
        echo -e "${GREEN}IPv6 configuration updated successfully${NC}"
        echo -e "${GREEN}Added IPv6: ${ipv6}/64${NC}"
    else
        echo -e "${YELLOW}No changes needed${NC}"
    fi
}

# Debian 批量绑定
BatchDebian() {
    local start=$1
    local end=$2
    local start_num=$(printf %d 0X${start##*:} 2>/dev/null)
    local end_num=$(printf %d 0X${end##*:} 2>/dev/null)
    
    if [ -z "$start_num" ] || [ -z "$end_num" ]; then
        echo -e "${RED}Error: Invalid IPv6 address format${NC}"
        exit 1
    fi
    
    local prefix=${start%:*}
    local total=$((end_num - start_num + 1))
    
    if [ $total -le 0 ]; then
        echo -e "${RED}Error: End address must be greater than start address${NC}"
        exit 1
    fi
    
    [ -f $NET_CONFIG_FILE ] && cp $NET_CONFIG_FILE ${NET_CONFIG_FILE}.bak
    
    # 检查是否已存在IPv6配置
    if grep -q "iface $NET_INTERFACE inet6 static" $NET_CONFIG_FILE 2>/dev/null; then
        # 在配置段中添加新地址
        local current_num=$start_num
        for ((i=1; i<=$total; i++)); do
            local current=$(printf "%x" $current_num)
            local ip="${prefix}:${current}/64"
            if ! grep -q "address $ip" $NET_CONFIG_FILE 2>/dev/null; then
                sed -i "/iface $NET_INTERFACE inet6 static/a\    address $ip" $NET_CONFIG_FILE
            fi
            current_num=$((current_num + 1))
        done
    else
        # 创建新的配置段
        local ipgw=$(GetIPv6Gateway "$start")
        local dns_servers="dns-nameservers 240C::6666 2001:4860:4860::8888"
        
        cat >> $NET_CONFIG_FILE << EOF

# IPv6 Configuration
iface $NET_INTERFACE inet6 static
EOF
        
        local current_num=$start_num
        for ((i=1; i<=$total; i++)); do
            local current=$(printf "%x" $current_num)
            echo "    address ${prefix}:${current}/64" >> $NET_CONFIG_FILE
            current_num=$((current_num + 1))
        done
        
        cat >> $NET_CONFIG_FILE << EOF
    gateway $ipgw
    $dns_servers
EOF
    fi
    
    restartflag=1
    
    # 重启网络
    if [ $restartflag -eq 1 ]; then
        systemctl restart networking 2>/dev/null
        echo -e "${GREEN}Batch IPv6 binding completed${NC}"
        echo -e "${GREEN}Added $total IPv6 addresses${NC}"
        echo -e "${YELLOW}IP Range:${NC} $start - $end"
    fi
}

# Ubuntu 20+ Netplan 配置
SetupUbuntu() {
    local ipv6=$1
    local ipgw=$(GetIPv6Gateway "$ipv6")
    
    [ -f $NET_CONFIG_FILE ] && cp $NET_CONFIG_FILE ${NET_CONFIG_FILE}.bak
    
    # 读取现有配置
    local yaml_content=""
    if [ -f "$NET_CONFIG_FILE" ]; then
        yaml_content=$(cat "$NET_CONFIG_FILE")
    fi
    
    # 检查是否已存在该IP
    if echo "$yaml_content" | grep -q " - ${ipv6}/64" 2>/dev/null; then
        echo -e "${YELLOW}IPv6 address $ipv6 already exists${NC}"
        return
    fi
    
    # 构建新的配置
    local temp_file=$(mktemp)
    
    # 提取现有配置并添加新IP
    if [ -f "$NET_CONFIG_FILE" ]; then
        # 使用Python或awk处理YAML（这里使用sed简单处理）
        # 在addresses列表中添加新IP
        if grep -q "addresses:" "$NET_CONFIG_FILE"; then
            # 在addresses列表的最后添加新IP
            sed -i "/addresses:/a\        - ${ipv6}/64" "$NET_CONFIG_FILE"
        else
            # 如果没有addresses段，重新生成完整配置
            cat > "$NET_CONFIG_FILE" << EOF
network:
  version: 2
  ethernets:
    $NET_INTERFACE:
      dhcp4: false
      dhcp6: false
      gateway4: $IPV4_GATEWAY
      gateway6: $ipgw
      addresses:
        - $IPV4_ADDR
        - ${ipv6}/64
      nameservers:
        addresses:
          - 240C::6666
          - 2001:4860:4860::8888
          - 223.5.5.5
          - 114.114.114.114
EOF
        fi
    else
        # 创建新配置文件
        cat > "$NET_CONFIG_FILE" << EOF
network:
  version: 2
  ethernets:
    $NET_INTERFACE:
      dhcp4: false
      dhcp6: false
      gateway4: $IPV4_GATEWAY
      gateway6: $ipgw
      addresses:
        - $IPV4_ADDR
        - ${ipv6}/64
      nameservers:
        addresses:
          - 240C::6666
          - 2001:4860:4860::8888
          - 223.5.5.5
          - 114.114.114.114
EOF
    fi
    
    netplan apply 2>/dev/null
    echo -e "${GREEN}IPv6 configuration updated successfully${NC}"
    echo -e "${GREEN}Added IPv6: ${ipv6}/64${NC}"
}

# Ubuntu 20+ Netplan 批量绑定
BatchUbuntu() {
    local start=$1
    local end=$2
    local start_num=$(printf %d 0X${start##*:} 2>/dev/null)
    local end_num=$(printf %d 0X${end##*:} 2>/dev/null)
    
    if [ -z "$start_num" ] || [ -z "$end_num" ]; then
        echo -e "${RED}Error: Invalid IPv6 address format${NC}"
        exit 1
    fi
    
    local prefix=${start%:*}
    local total=$((end_num - start_num + 1))
    
    if [ $total -le 0 ]; then
        echo -e "${RED}Error: End address must be greater than start address${NC}"
        exit 1
    fi
    
    local ipgw=$(GetIPv6Gateway "$start")
    
    [ -f $NET_CONFIG_FILE ] && cp $NET_CONFIG_FILE ${NET_CONFIG_FILE}.bak
    
    # 构建IP列表
    local ip_list="$IPV4_ADDR"
    local current_num=$start_num
    for ((i=1; i<=$total; i++)); do
        local current=$(printf "%x" $current_num)
        ip_list="$ip_list\n        - ${prefix}:${current}/64"
        current_num=$((current_num + 1))
    done
    
    # 生成完整的netplan配置
    cat > "$NET_CONFIG_FILE" << EOF
network:
  version: 2
  ethernets:
    $NET_INTERFACE:
      dhcp4: false
      dhcp6: false
      gateway4: $IPV4_GATEWAY
      gateway6: $ipgw
      addresses:
        - $ip_list
      nameservers:
        addresses:
          - 240C::6666
          - 2001:4860:4860::8888
          - 223.5.5.5
          - 114.114.114.114
EOF
    
    netplan apply 2>/dev/null
    echo -e "${GREEN}Batch IPv6 binding completed${NC}"
    echo -e "${GREEN}Added $total IPv6 addresses${NC}"
    echo -e "${YELLOW}IP Range:${NC} $start - $end"
}

# 主函数
Main() {
    CheckOS
    
    # 如果没有参数，显示帮助
    if [ $# -eq 0 ]; then
        Help
        exit 0
    fi
    
    while [ $# -gt 0 ]; do
        case $1 in
            '-i' | '--info')
                ShowNetworkInfo
                exit 0
                ;;
            '-s' | '--single')
                if [ -z "$2" ]; then
                    echo -e "${RED}Error: IPv6 address required${NC}"
                    exit 1
                fi
                # 验证IPv6地址格式
                if ! echo "$2" | grep -qE '^([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$|^([0-9a-fA-F]{1,4}:){1,7}:$|^([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}$'; then
                    echo -e "${RED}Error: Invalid IPv6 address format${NC}"
                    exit 1
                fi
                
                case $OS in
                    centos|rhel|fedora)
                        SetupCentOS $2
                        ;;
                    debian)
                        SetupDebian $2
                        ;;
                    ubuntu)
                        if [ "$OSVer" -ge 20 ]; then
                            SetupUbuntu $2
                        else
                            SetupDebian $2
                        fi
                        ;;
                    *)
                        echo -e "${RED}Unsupported OS: $OS${NC}"
                        exit 1
                        ;;
                esac
                exit 0
                ;;
            '-b' | '--batch')
                if [ -z "$2" ] || [ -z "$3" ]; then
                    echo -e "${RED}Error: Start and end IPv6 addresses required${NC}"
                    exit 1
                fi
                case $OS in
                    centos|rhel|fedora)
                        BatchCentOS $2 $3
                        ;;
                    debian)
                        BatchDebian $2 $3
                        ;;
                    ubuntu)
                        if [ "$OSVer" -ge 20 ]; then
                            BatchUbuntu $2 $3
                        else
                            BatchDebian $2 $3
                        fi
                        ;;
                    *)
                        echo -e "${RED}Unsupported OS: $OS${NC}"
                        exit 1
                        ;;
                esac
                exit 0
                ;;
            '-h' | '--help')
                Help
                exit 0
                ;;
            *)
                echo -e "${RED}Unknown option: $1${NC}"
                Help
                exit 1
                ;;
        esac
        shift
    done
}

# 执行主函数
Main "$@"