#!/bin/bash
export HISTCONTROL=ignorespace

# 获取 /etc/sysconfig/network-scripts 目录下所有以 ifcfg-ppp 开头的文件
get_ppp_interface_names() {
    for file in /etc/sysconfig/network-scripts/ifcfg-ppp*; do
        if [[ -f $file ]]; then
            basename "$file" | sed 's/^ifcfg-//'
        fi
    done | sort -V
}

# 获取指定 PPP 接口的 IP 地址
get_ppp_ip_address() {
    local iface=$1
    #cat $log_file | grep $pid | grep 'local  IP address' | tail -n 1 | awk '{print $9}' | cut -d/ -f1
    #/usr/sbin/pppoe-status /etc/sysconfig/network-scripts/ifcfg-$iface|awk '$1~"inet$" && $2~"^[0-9]"{print $2 }'
    ip addr | grep -E "$iface($| )" | awk '{print $2}'
}


# 获取指定IP地址的linkname
get_ip_linkname() {
    local current_ip=$1
    ip addr | grep -E "$current_ip($| )" | awk '{print $7}'
    #/usr/sbin/pppoe-status /etc/sysconfig/network-scripts/ifcfg-$iface |grep state | awk '{print $2}'
}

# 获取指定 PPP 接口的宽带账号
get_ppp_user() {
    local iface=$1
    local config_file="/etc/sysconfig/network-scripts/ifcfg-$iface"
    
    if [ ! -f "$config_file" ]; then
        echo "文件 '$config_file' 未找到"
        return 1
    fi

    local user=$(grep -E '^USER=' "$config_file" | cut -d= -f2)
    
    if [ -z "$user" ]; then
        echo "未找到 USER 信息"
        return 1
    fi

    echo "$user"
}

# 初始化日志文件
log_file="/var/log/ppp_speed.log"
echo "初始化日志文件" > $log_file

# 无限循环，持续监控 PPP 接口的 IP 地址变化
declare -A ip_addrs
declare -A ip_addrs_public
while true; do
    # 获取 PPP 接口名
    ppp_interfaces=$(get_ppp_interface_names)

    for iface in $ppp_interfaces; do
        # 获取宽带账号
        ppp_user=$(get_ppp_user "$iface")
        
        # 获取PID
        pid=$(ps -aux | grep -E "pppd call" | grep -E "$iface($| )" | grep -v 'grep' | awk '{print $2}')
        
        # 获取当前 IP 地址
        current_ip=$(get_ppp_ip_address "$iface")
        
        # 获取linkname
        linkname=$(get_ip_linkname "$current_ip")
        
        # 获取之前存储的 IP 地址
        previous_ip=${ip_addrs[$iface]}
        
        #查看当前接口是否有进程
        pppd_status=$(ps -ef | grep -E "pppd call" | grep -E "$iface($| )" | grep -v 'grep' | wc -l)
        
        if [[ $pppd_status -lt 1 ]]; then
            echo "$(date): $linkname -> $iface 进程不存在,准备启动$iface" >> $log_file
            # 启动 PPP 接口
            sudo sh /opt/pppoe/ppp_check.sh
            sleep 15
            echo "$(date): $linkname -> $iface 启动成功" >> $log_file
        else
            echo "$(date): $linkname -> $iface 当前进程ID: $pid" >> $log_file
        fi
        #如果$current_ip不为空，就执行下面的存起来
        if [[ -n "$current_ip" ]]; then
            echo "$(date): $linkname -> $iface IP 地址变化: $previous_ip -> $current_ip" >> $log_file
             # 如果 IP 地址发生变化，则更新日志并修改变量
            if [[ "$current_ip" != "$previous_ip" ]]; then
                # 更新路由规则
                echo "$(date): $linkname -> $iface 的当前IP地址：$current_ip" >> $log_file
                sudo sh /opt/pppoe/ppp_rule_check.sh
                # 执行 curl 命令并将结果存储到变量中
                curl_output=$(curl -s --interface $linkname https://eapi.jiasu123.net/bs/bdCoSpeed/deaab7633f2c636410b50f3be3b80f2a8190efa82e9f11141c12efcded2c841ff9f4e2d6ef420479f2200a02704a0393)
                #curl_exit_code=$?
                sleep 1
                # 提取 JSON 中的 ad 字段并解析 sc:: 后面的部分
                ad_value=$(echo "$curl_output" | jq -r '.data.ad')
                if [ -z "$ad_value" ]; then
                    echo "$(date): $linkname -> $iface 未提取到宽带账号，请求失败，可能没网,5秒后继续下一步" >> $log_file
                    sleep 5
                    continue
                fi
                sp_user=$(echo "$ad_value" | grep -oP '::\K.*')
                sp_msg=$(echo "$curl_output" | jq -r '.msg')
                # 将 curl 的结果追加到日志文件
                echo "$(date): $linkname -> $iface $ad_value $sp_msg" >> $log_file
                sleep 1
                # 检查 curl 命令是否成功执行并且有输出
                #if [[ $curl_exit_code -ne 0 || -z "$curl_output" ]]; then
                if [[ -z "$curl_output" ]]; then
                    echo "$(date): $linkname -> $iface 请求失败，可能没网,5秒后重新尝试" >> $log_file
                    sudo sh /opt/pppoe/ppp_rule_check.sh
                    sleep 5
                    curl_output=$(curl -s --interface $linkname https://eapi.jiasu123.net/bs/bdCoSpeed/deaab7633f2c636410b50f3be3b80f2a8190efa82e9f11141c12efcded2c841ff9f4e2d6ef420479f2200a02704a0393)
                    echo "$(date): $linkname -> $iface $curl_output" >> $log_file
                    if [[ -z "$curl_output" ]]; then
                        kill $pid
                        continue
                    fi
                else
                    # 对比 curl 结果sp_user是否ppp_user相同，如果相同，代表成功，否则代表失败"
                    if [[ -z "$sp_user" || "$ppp_user" != *"$sp_user"* ]]; then
                        echo "$(date): $linkname -> $iface $ppp_user 提速失败,5秒后重启PPP接口" >> $log_file
                        sleep 1
                        # 停止PPP 接口
                        kill $pid
                        sleep 5
                        echo "$(date): $linkname -> $iface kill断开$iface 成功" >> $log_file
                    else
                        #如果$sp_msg变量中，不包含：“提速成功” 或者 “正在加速中” 或者 “重复提速” 就执行，
                        if ! echo "$sp_msg" | grep -qE "提速成功|正在加速中|重复提速"; then
                            echo "$(date): $linkname -> $iface $ppp_user 匹配正确，但提速失败，5秒后重启PPP接口" >> $log_file
                            # 停止PPP 接口
                            kill $pid
                            sleep 5
                            echo "$(date): $linkname -> $iface kill断开$iface 成功" >> $log_file
                        else
                            echo "$(date): $linkname -> $iface $ppp_user 提速成功" >> $log_file
                            ip_addrs[$iface]=$current_ip
                        fi    
                    fi
                fi
            else
                echo "$(date): $linkname -> $iface IP无变化，跳过$ppp_user 提速任务" >> $log_file
                continue
            fi
        else
            echo "$(date): $linkname -> $iface 拨号失败，等待拨号..." >> $log_file
            continue
        fi
    done
    # 等待一段时间再进行下一次检查
    echo "$(date): 本次循环结束，20秒后启动下一次循环....." >> $log_file
    sleep 20
done