#!/bin/sh

# 配置参数
sleep 35

ID=$(hexdump -s 0x28 -n 6 -e '6/1 "%02x"' /dev/mtd2)
server="br.ampo.tech"
user="ampo"
pswd="ampo0127"

# HMAC-SHA256 密钥 (用于验证 secret)
KEY_HEX="db09de4592069e3bf060c8d9ab21f3128aad53a94cee02b16fc261b6ed3b840db09de4592069e3bf060c8d9ab21f3128aad53a94cee02b16fc261b6ed3b840"

# 日志文件
LOG_FILE="/tmp/reset_daemon.log"

log_msg() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') $1" >> "$LOG_FILE"
}

# ==================== Secret 验证函数 ====================

hex2bin() {
    awk -v h="$1" 'BEGIN{for(i=1;i<=length(h);i+=2){c1=index("0123456789abcdef",tolower(substr(h,i,1)))-1;c2=index("0123456789abcdef",tolower(substr(h,i+1,1)))-1;printf "%c",c1*16+c2}}'
}

xor_key() {
    awk -v h="$1" -v x="$2" 'function xorb(a,c,  r,bit){r=0;bit=1;while(a>0||c>0){if(((a%2)+(c%2))==1)r+=bit;a=int(a/2);c=int(c/2);bit*=2}return r} BEGIN{m=0;for(i=1;i<=length(h);i+=2){c1=index("0123456789abcdef",tolower(substr(h,i,1)))-1;c2=index("0123456789abcdef",tolower(substr(h,i+1,1)))-1;b[m++]=c1*16+c2}for(i=m;i<64;i++)b[i]=0;for(i=0;i<64;i++)printf "%02x",xorb(b[i],x)}'
}

sha_hex() { 
    sha256sum | cut -d' ' -f1
}

b64url_from_hex() {
    awk -v h="$1" 'BEGIN{A="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";n=0;for(i=1;i<=length(h);i+=2){c1=index("0123456789abcdef",tolower(substr(h,i,1)))-1;c2=index("0123456789abcdef",tolower(substr(h,i+1,1)))-1;b[n++]=c1*16+c2}out="";i=0;while(i<n){r=n-i;b0=b[i];b1=(r>1)?b[i+1]:0;b2=(r>2)?b[i+2]:0;out=out substr(A,int(b0/4)+1,1);out=out substr(A,(b0%4)*16+int(b1/16)+1,1);if(r>1)out=out substr(A,(b1%16)*4+int(b2/64)+1,1);if(r>2)out=out substr(A,(b2%64)+1,1);i+=3}print out}'
}

inner_pre() { hex2bin "$1"; printf '%s' "$2"; }
outer_pre() { hex2bin "$1"; hex2bin "$2"; }

generate_expected_secret() {
    local mac="$1"
    
    # 清理 MAC 地址格式
    mac=$(printf '%s' "$mac" | tr -d ':-' | tr 'A-F' 'a-f')
    
    if [ ${#mac} -ne 12 ]; then
        log_msg "ERROR: Invalid MAC address [$mac]"
        return 1
    fi
    
    local ipad_hex opad_hex inner outer
    
    ipad_hex=$(xor_key "$KEY_HEX" 54)
    opad_hex=$(xor_key "$KEY_HEX" 92)
    inner=$(inner_pre "$ipad_hex" "$mac" | sha_hex)
    outer=$(outer_pre "$opad_hex" "$inner" | sha_hex)
    
    echo "v1.$(b64url_from_hex "$outer")"
}

verify_secret() {
    local received_secret="$1"
    local expected_secret
    
    # 从 /dev/mtd2 获取 MAC
    local eth_mac
    eth_mac=$(hexdump -s 0x28 -n 6 -e '5/1 "%02x:" 1/1 "%02x"' /dev/mtd2 2>/dev/null)
    
    if [ -z "$eth_mac" ]; then
        eth_mac=$(cat /sys/class/net/eth0/address 2>/dev/null)
    fi
    
    if [ -z "$eth_mac" ]; then
        log_msg "ERROR: Cannot get MAC address"
        return 1
    fi
    
    expected_secret=$(generate_expected_secret "$eth_mac")
    
    if [ "$received_secret" = "$expected_secret" ]; then
        log_msg "Secret verification PASSED"
        return 0
    else
        log_msg "Secret verification FAILED (received: ${received_secret:0:10}...)"
        return 1
    fi
}

# ==================== 清理用户数据函数 ====================

cleanup_user_data() {
    log_msg "Starting factory reset..."
    
    # 清空应用程序配置
    rm -rf /etc/config/zigbee
    rm -rf /etc/config/zwave
    rm -rf /etc/config/ha_web_ui
    rm -rf /etc/config/ha_register

    # 清空 wifi 配置
    rm -rf /etc/config/wifi_ssid
    rm -rf /etc/config/wifi_pass

    # 清空 gateway_install_id
    rm -rf /root/gateway_install_id

    # 转移文件夹
    cp -rf /root/default/zigbee /etc/config/
    cp -rf /root/default/zwave /etc/config/
    cp -rf /root/default/ha_web_ui /etc/config/
    cp -rf /root/default/ha_register /etc/config/
    
    log_msg "Factory reset completed"
    mosquitto_pub -h $server -t "gw/$ID/api/factory_reset/result" -m "{\"success\": true, \"args\": [], \"data\": { \"state\": \"resetting\" }, \"error\": null}" -u $user -P $pswd -p 1883
    log_msg "reboot after 3s"
    sleep 3 
    reboot
}

# ==================== 命令白名单 ====================

execute_command() {
    local cmd="$1"
    
    case "$cmd" in
        "factory_reset")
            cleanup_user_data
            ;;
        "reboot")
            log_msg "Reboot command received"
            echo "Rebooting..."
            reboot
            ;;
        "status")
            log_msg "Status check requested"
            echo "Device ID: $ID"
            echo "Uptime: $(uptime)"
            echo "Memory: $(free -m 2>/dev/null || cat /proc/meminfo | head -5)"
            ;;
        *)
            log_msg "ERROR: Unknown command [$cmd]"
            echo "Error: Unknown command"
            return 1
            ;;
    esac
}

# ==================== JSON 解析辅助函数 ====================

# 简单的 JSON 字段提取 (适用于简单结构)
json_get_array_first() {
    local json="$1"
    # 提取 args 数组的第一个对象的 secret 字段
    echo "$json" | grep -o '"secret"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed 's/"secret"[[:space:]]*:[[:space:]]*"//' | sed 's/"$//'
}

# ==================== 主循环 ====================

log_msg "Reset daemon started (Device ID: $ID)"

while true; do
    # 接收来自云端的消息
    msg=$(mosquitto_sub -h $server -p 1883 -t "gw/$ID/api/factory_reset/set" -C 1 -u $user -P $pswd 2>&1)
    
    if [ $? -ne 0 ]; then
        log_msg "ERROR: mosquitto_sub failed: $msg"
        sleep 5
        continue
    fi
    
    log_msg "Received message: ${msg:0:100}..."
    
    # 解析 JSON 获取 secret
    secret=$(json_get_array_first "$msg")
    
    if [ -z "$secret" ]; then
        log_msg "ERROR: No secret found in message"
        # mosquitto_pub -h $server -t "/pub/router/$ID/response" -m '{"error": "No secret provided"}' -u $user -P $pswd -p 1883
        continue
    fi
    
    # 验证 secret
    if ! verify_secret "$secret"; then
        log_msg "ERROR: Invalid secret, rejecting command"
        # mosquitto_pub -h $server -t "/pub/router/$ID/response" -m '{"error": "Authentication failed"}' -u $user -P $pswd -p 1883
        continue
    fi
    
    # 解析命令类型 (从 topic 或 message 中获取)
    # 这里假设 topic 中的 "factory_reset" 就是命令
    cmd="factory_reset"
    
    # 执行命令
    result=$(execute_command "$cmd" 2>&1)
    exit_code=$?
    
    log_msg "Command executed with exit code: $exit_code"
done
