#!/bin/sh
#
# OpenWrt WiFi 自动配置脚本 v6
# 用法:
#   ./wifi_connect.sh <SSID> <密码> [加密方式]
#   ./wifi_connect.sh -d              (诊断模式)
#

RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; NC='\033[0m'
log_info()  { echo -e "${GREEN}[INFO]${NC}  $1"; }
log_warn()  { echo -e "${YELLOW}[WARN]${NC}  $1"; }
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
log_ok()    { echo -e "${GREEN}[ OK]${NC}  $1"; }

die() { log_error "$1"; exit 1; }

# ========================================
# 诊断模式
# ========================================
run_diag() {
    echo ""
    echo "========== 内核无线 phy =========="
    ls /sys/class/ieee80211/ 2>/dev/null && echo "(phy 设备存在)" || echo "(无)"
    echo ""
    echo "========== iwinfo =========="
    iwinfo 2>/dev/null || echo "(无输出)"
    echo ""
    echo "========== iw dev =========="
    iw dev 2>/dev/null || echo "(无输出)"
    echo ""
    echo "========== 网卡列表 =========="
    ifconfig 2>/dev/null | grep -E "^[a-z]|inet "
    echo ""
    echo "========== UCI wireless =========="
    uci show wireless 2>/dev/null || echo "(空)"
    echo ""
    echo "========== UCI network =========="
    uci show network 2>/dev/null || echo "(空)"
    echo ""
    echo "========== UCI firewall =========="
    uci show firewall 2>/dev/null || echo "(空)"
    echo ""
    echo "========== 内核日志 (wireless) =========="
    dmesg 2>/dev/null | grep -iE "wlan|wireless|phy|fw|firmware|80211|mac80211|mt76" | tail -20
    exit 0
}

[ "$1" = "-d" ] && run_diag

# ========================================
# 无线网卡检测
# ========================================
detect_wdev() {
    local dev=""
    iwinfo 2>/dev/null | grep "^[a-z]" | head -1 | awk '{print $1}'
}

# ========================================
# 清理孤儿 wifi-iface
# ========================================
cleanup_orphan_ifaces() {
    uci show wireless 2>/dev/null | sed 's/=.*//' | while read section; do
        case "$section" in
            wireless\.@wifi-iface\[*\]|wireless\.cfg*)
                DEV=$(uci get "${section}.device" 2>/dev/null || true)
                MODE=$(uci get "${section}.mode" 2>/dev/null || true)
                if [ -z "$DEV" ] && [ -z "$MODE" ]; then
                    log_warn "清理孤儿: ${section}"
                    uci delete "$section" 2>/dev/null || true
                fi
                ;;
        esac
    done
    uci commit wireless 2>/dev/null || true
}

# ========================================
# 主流程
# ========================================
main() {
    echo ""
    echo "======================================"
    echo "  OpenWrt WiFi 一键配置 v6"
    echo "======================================"
    echo ""

    [ "$(id -u)" -ne 0 ] && die "请使用 root 权限"

    # ---- 获取参数 ----
    SSID=""; PASSWORD=""; ENC="psk2"
    if [ -n "$1" ] && [ -n "$2" ]; then
        SSID="$1"; PASSWORD="$2"
        [ -n "$3" ] && ENC="$3"
        log_info "SSID=${SSID}  加密=${ENC}"
    else
        echo -n "SSID: "; read -r SSID
        echo -n "密码: "; read -r PASSWORD
        echo -n "加密 [psk2]: "; read -r ENC
        [ -z "$ENC" ] && ENC="psk2"
    fi
    [ -z "$SSID" ] && die "SSID 不能为空"

    # ========================================
    # 1. 检查硬件
    # ========================================
    log_info "Step 1/5: 检查无线硬件..."
    ls /sys/class/ieee80211/phy* >/dev/null 2>&1 || die "无 phy 设备，请检查 kmod 驱动"
    log_ok "phy 设备: $(ls /sys/class/ieee80211/ 2>/dev/null | tr '\n' ' ')"

    # ========================================
    # 2. 配置 UCI
    # ========================================
    log_info "Step 2/5: 配置 UCI wireless/network/firewall..."

    # 备份
    cp /etc/config/wireless /etc/config/wireless.backup 2>/dev/null || true

    # 清理 + 重新生成
    cleanup_orphan_ifaces
    wifi config 2>/dev/null || true

    # 确保 radio0 配置正确
    if ! uci get wireless.radio0 >/dev/null 2>&1; then
        die "wireless.radio0 不存在，wifi config 可能失败"
    fi
    uci set wireless.radio0.disabled='0'
    uci set wireless.radio0.channel='auto'

    # 找到或创建 STA iface
    IFACE=""
    FOUND=$(uci show wireless 2>/dev/null | sed 's/=.*//' | grep -E "wifi-iface" | head -1)
    if [ -n "$FOUND" ]; then
        IFACE=$(echo "$FOUND" | sed 's/wireless\.//')
    else
        uci add wireless wifi-iface
        IFACE="@wifi-iface[0]"
    fi

    uci set "wireless.${IFACE}.device=radio0"
    uci set "wireless.${IFACE}.mode=sta"
    uci set "wireless.${IFACE}.network=wwan"
    uci set "wireless.${IFACE}.ssid=${SSID}"
    uci set "wireless.${IFACE}.encryption=${ENC}"
    uci set "wireless.${IFACE}.key=${PASSWORD}"
    uci commit wireless
    log_ok "wireless: radio0 + ${IFACE} -> sta -> ${SSID}"

    # network.wwan
    uci get network.wwan >/dev/null 2>&1 || uci set network.wwan=interface
    uci set network.wwan.proto='dhcp'
    uci set network.wwan.metric='10'
    uci commit network
    log_ok "network: wwan (dhcp, metric=10)"

    # firewall: 把 wwan 加入 wan zone
    uci show firewall 2>/dev/null | grep "=zone" | sed 's/=.*//' | while read z; do
        [ "$(uci get "${z}.name" 2>/dev/null)" = "wan" ] || continue
        NW=$(uci get "${z}.network" 2>/dev/null)
        echo "$NW" | grep -q "wwan" && continue
        uci set "${z}.network=${NW} wwan"
        log_ok "firewall: wwan -> wan zone"
        break
    done
    uci commit firewall 2>/dev/null || true

    # ========================================
    # 3. 启动无线
    # ========================================
    log_info "Step 3/5: 启动无线接口..."

    # 先 down 清理状态
    wifi down 2>/dev/null || true
    sleep 1

    # wifi up 创建接口
    wifi up 2>/dev/null
    RC=$?
    sleep 2

    WDEV=$(detect_wdev)
    if [ -z "$WDEV" ]; then
        # wifi up 可能返回非 0 但实际成功了，再等一等
        sleep 2
        WDEV=$(detect_wdev)
    fi

    if [ -z "$WDEV" ]; then
        log_error "wifi up 后仍未创建接口 (RC=${RC})"
        echo ""
        log_info "请手动排查:"
        echo "  iwinfo"
        echo "  dmesg | tail -20"
        echo "  wifi status"
        exit 1
    fi
    log_ok "无线接口: ${WDEV}"

    # ========================================
    # 4. 等待连接
    # ========================================
    log_info "Step 4/5: 等待连接..."

    /etc/init.d/firewall restart 2>/dev/null || true
    sleep 1

    # 扫描目标 AP
    log_info "扫描 ${SSID}..."
    iwinfo "$WDEV" scan 2>/dev/null | grep -q "$SSID" && log_ok "找到 ${SSID}" || log_warn "未扫描到 ${SSID}，可能信号弱或 SSID 隐藏"

    # 等待关联
    log_info "关联中..."
    for i in $(seq 1 20); do
        sleep 2
        INFO=$(iwinfo "$WDEV" info 2>/dev/null)
        ASSOC=$(echo "$INFO" | grep "Access Point" | awk '{print $NF}')
        if [ -n "$ASSOC" ] && [ "$ASSOC" != "Unknown" ] && [ "$ASSOC" != "Not-Associated" ]; then
            log_ok "已关联: ${ASSOC}"
            SSID_FOUND=$(echo "$INFO" | grep "ESSID" | sed 's/.*ESSID: //' | tr -d '"')
            log_info "ESSID: ${SSID_FOUND}"
            break
        fi
        echo -n "."
    done
    echo ""

    # 启动 wwan DHCP
    ifup wwan 2>/dev/null || true
    sleep 2

    # 等待 DHCP
    log_info "获取 IP..."
    for i in $(seq 1 15); do
        IP=$(ip addr show "$WDEV" 2>/dev/null | grep "inet " | awk '{print $2}' | head -1)
        if [ -n "$IP" ]; then
            log_ok "IP: ${IP}"
            break
        fi
        sleep 2
        ifup wwan 2>/dev/null || true
        echo -n "."
    done
    echo ""

    # Ping 验证
    for i in $(seq 1 5); do
        ping -c 1 -W 2 223.5.5.5 >/dev/null 2>&1 && { log_ok "外网连通!"; break; }
        sleep 2
    done

    # ========================================
    # 5. 状态
    # ========================================
    log_info "Step 5/5: 状态"
    echo ""
    echo "========== ${WDEV} =========="
    iwinfo "$WDEV" info 2>/dev/null
    echo ""
    ip addr show "$WDEV" 2>/dev/null | grep -E "inet |state"
    echo ""
    route -n 2>/dev/null | head -10

    echo ""
    log_info "完成！"
    echo ""
    echo "可选操作:"
    echo "  uci set network.lan.ipaddr='192.168.21.1'"
    echo "  uci set dhcp.lan.start='10' ; uci set dhcp.lan.limit='230'"
    echo "  uci commit && /etc/init.d/network restart"
    echo "  sed -i 's/21.02-SNAPSHOT/21.02.7/g' /etc/opkg/distfeeds.conf"
}

main "$@"
