#!/bin/bash
set -eo pipefail

# 清理函数：用于删除指定任务ID对应的网络命名空间和虚拟网卡资源
cleanup() {
    local TASK_ID=$1
    local NS_NAME="ns_$TASK_ID"
    local VETH_PEER="veth_$TASK_ID"
    local VETH_NAME="vh_$TASK_ID"
    
    echo "开始清理任务 $TASK_ID 的资源..."
    
    # 清理虚拟网卡（若存在）
    if ip link show "$VETH_PEER" &>/dev/null; then
        echo "删除虚拟网卡 $VETH_PEER"
        ip link del "$VETH_PEER" || echo "警告: 删除虚拟网卡 $VETH_PEER 失败"
    fi
    
    # 清理网络命名空间（若存在）
    if ip netns show "$NS_NAME" &>/dev/null; then
        echo "删除网络命名空间 $NS_NAME"
        ip netns del "$NS_NAME" || echo "警告: 删除网络命名空间 $NS_NAME 失败"
    fi
    
    echo "任务 $TASK_ID 的资源清理完成"
}

# 状态上报函数：向指定接口上报任务状态（仅包含taskId和state）
report_state() {
    local TASK_ID=$1
    local STATE=$2
    local REMARK=$3
    local AUTHCODE=$4
    
    # 构造JSON格式的上报数据（确保JSON语法正确，无多余逗号）
    local report_data=$(jq -n \
        --arg taskId "$TASK_ID" \
        --arg state "$STATE" \
        --arg remark "$REMARK" \
        --arg authCode "$AUTHCODE" \
        '{
            "taskId": $taskId,
            "state": $state,
            "authCode": $authCode,
            "remark": $remark
        }')
    
    # 发送POST请求上报状态
    local response=$(curl -s -X POST -H "Content-Type: application/json" -d "$report_data" "http://localhost:8090/superbot/client/task/state/report")
    local exit_code=$?
    
    # 输出上报结果（成功/失败）
    if [ $exit_code -ne 0 ]; then
        echo "警告: 状态上报失败 (状态码: $STATE)"
    else
        echo "状态上报成功 (状态码: $STATE)"
    fi
}


# 脚本核心逻辑开始
# 1. 校验任务ID参数（确保脚本接收任务ID作为第一个参数）
if [ -z "$1" ]; then
    echo "错误: 请传入任务ID作为第一个参数（格式：./script.sh <TASK_ID>）"
    exit 1
fi
TASK_ID=$1
NS_NAME="ns_$TASK_ID"       # 网络命名空间名称
VETH_PEER="veth_$TASK_ID"   # 主机侧虚拟网卡名称
VETH_NAME="vh_$TASK_ID"     # 命名空间内虚拟网卡名称
BRIDGE="br0"                # 网桥名称（需确保系统中已存在该网桥）
CURL_PIDS=""                # 预留curl进程ID变量（暂未使用）


echo "==================== 开始执行任务 $TASK_ID ===================="

# 3. 预处理：清理已存在的同名资源（避免创建时冲突）
echo "检查并清理已存在的同名资源..."
# 清理同名网络命名空间
if ip netns show "$NS_NAME" &>/dev/null; then
    echo "发现已存在的网络命名空间 $NS_NAME，执行清理"
    cleanup $TASK_ID
fi
# 清理同名虚拟网卡
if ip link show "$VETH_PEER" &>/dev/null; then
    echo "发现已存在的虚拟网卡 $VETH_PEER，执行清理"
    ip link del "$VETH_PEER" || { echo "错误: 无法删除已存在的虚拟网卡 $VETH_PEER"; exit 1; }
fi
echo "创建网络命名空间和虚拟网卡..."
ip netns add $NS_NAME || { echo "创建网络命名空间失败"; exit 1; }
    
echo "创建虚拟网卡对"
ip link add $VETH_PEER type veth peer name $VETH_NAME || { echo "错误: 创建veth对失败"; exit 1; } 

echo "将虚拟网卡移动到命名空间"
ip link set $VETH_NAME netns $NS_NAME || { echo "错误: 无法将veth加入命名空间"; exit 1; }

echo "将veth加入网桥 $BRIDGE..."
ip link set $VETH_PEER master $BRIDGE || { echo "错误: 无法将veth加入网桥"; exit 1; }

echo "启用虚拟网卡"
ip link set $VETH_PEER up || { echo "错误: 无法启动veth设备"; exit 1; } 

# DHCP获取IP地址
echo "配置命名空间内DHCP自动获取IP..."
# 启用命名空间内回环网卡（lo）
ip netns exec "$NS_NAME" ip link set lo up 2>/dev/null
# 启用命名空间内虚拟网卡
echo "  - 启用命名空间内虚拟网卡 $VETH_NAME"
ip netns exec "$NS_NAME" ip link set "$VETH_NAME" up 2>/dev/null || { echo "错误: 无法启动命名空间内veth $VETH_NAME"; report_state $TASK_ID 3; cleanup $TASK_ID; exit 1; }
# 释放旧IP（避免地址冲突）
ip netns exec "$NS_NAME" dhclient -r "$VETH_NAME" 2>/dev/null || echo "警告: 清除网卡旧地址失败，继续执行"
# 重新通过DHCP获取IP
echo "  - 通过DHCP获取IP地址"
ip netns exec "$NS_NAME" dhclient "$VETH_NAME" 2>/dev/null || { echo "错误：无法通过DHCP获取IP地址"; report_state $TASK_ID 3; cleanup $TASK_ID; exit 1; }

echo "网络命名空间和虚拟网卡配置成功！"


# 6. 获取并校验命名空间内IP、MAC地址
echo "获取命名空间内IP和MAC地址..."
# 提取IPv4地址（
IP_ADDR=$(ip netns exec "$NS_NAME" ip -4 addr show "$VETH_NAME" | grep -oP '(?<=inet\s)\d+(\.\d+){3}/\d+' | sed 's/\/[0-9]*$//')
# 提取MAC地址（
MAC_ADDR=$(ip netns exec "$NS_NAME" ip link show "$VETH_NAME" | grep -oP '(?<=link/ether\s)\w+:\w+:\w+:\w+:\w+:\w+')

# 校验IP和MAC是否获取成功
if [ -z "$IP_ADDR" ] || [ -z "$MAC_ADDR" ]; then
    echo "错误: 获取IP或MAC地址失败（IP: $IP_ADDR, MAC: $MAC_ADDR）"
    report_state $TASK_ID 3
    cleanup $TASK_ID
    exit 1
else
   echo "  - 成功获取地址：IP=$IP_ADDR, MAC=$MAC_ADDR" 
#   report_state $TASK_ID 0    
fi

# 测试先访问baidu,能否会记录MAc
# ip netns exec "$NS_NAME" timeout 10  wget --tries=1 --limit-rate=100K  http://lemonwifi.cn -O /dev/null
ip netns exec "$NS_NAME"  ping -c 1 lemonwifi.cn

# 7. 向配置生成接口汇报IP/MAC信息
echo "向配置生成接口汇报地址信息..."
# 构造JSON格式的配置数据
config_data=$(jq -n \
    --arg taskId "$TASK_ID" \
    --arg ip "$IP_ADDR" \
    --arg mac "$MAC_ADDR" \
    '{
        "taskId": $taskId,
        "ipAddress": $ip,
        "macAddress": $mac
    }')

# 调用配置生成接口
config_response=$(curl -s -X POST -H "Content-Type: application/json" -d "$config_data" "http://localhost:8090/superbot/client/task/config/generate")
# 校验接口调用结果
if [ $? -ne 0 ]; then
    echo "错误: 配置生成接口调用失败"
    cleanup $TASK_ID
    exit 1
fi

# 保存接口响应到临时文件（便于后续解析）
temp_config_file=$(mktemp /root/software/superbot/tmp/config_response_${TASK_ID}_XXXXXX.json)
echo "$config_response" > "$temp_config_file"

# 校验接口返回状态（state=0表示成功）
state=$(jq -r '.state' "$temp_config_file")
if [ "$state" = "null" ] || [ "$state" -ne 0 ]; then
    echo "错误: 配置生成接口返回错误状态（state=$state）"
    cleanup $TASK_ID
    exit 1
else
    echo "  - 配置生成接口调用成功"  
fi

# 8. 执行认证接口调用
echo "调用认证接口完成认证..."
# 从配置响应中提取认证数据（.body.auth字段）
extracted_data=$(jq '.body.auth' "$temp_config_file")

# 调用认证接口
auth_response=$(curl -s -X POST -H "Content-Type: application/json" -d "$extracted_data" "https://lemonwifi.cn/ws/auth")
# 校验认证接口调用结果
[ $? -ne 0 ] && echo "配置生成接口调用失败" && cleanup $TASK_ID && exit 1

echo "认证信息: $auth_response"
# 校验认证结果（code=0表示认证成功）
#auth_code=$(echo "$auth_response" | jq -r '.code')
read auth_code auth_message <<< $(echo "$auth_response" | jq -r '.code, .message')
if [ "$auth_code" = "null" ] || [ "$auth_code" -ne 0 ]; then
    echo "错误: 认证失败（错误码: $auth_code,错误信息: $auth_message）"
   # echo "错误: 认证失败(返回参数: $auth_response)"
    report_state $TASK_ID 1 "$auth_message" $auth_code
    cleanup $TASK_ID
    exit 1
else
    echo "  - 认证成功!"
    report_state $TASK_ID 0  
fi

# 脚本执行完成
echo "==================== 任务 $TASK_ID 执行完成 ===================="
# 清理临时文件（避免残留）
rm -f "$temp_config_file"
exit 0

