#!/bin/bash
#########################################################
# hwinfo.sh – Hardware-/Netzwerk-Inventar an infosnow-API senden
#
# Wird von job.sh bei jedem Minuten-Poll aufgerufen, lädt aber
# nur einmal pro Boot tatsächlich hoch (Marker in /tmp, wird
# bei Reboot geleert) – bei fehlendem Token (Gerät noch nicht
# freigeschaltet) einfach still beenden, job.sh ruft eine
# Minute später erneut auf, kein eigener Retry-Loop nötig.
# Sammelt Netzwerk- (MAC/IP/Gateway/DNS) und Hardware-Eckdaten
# (Modell, CPU, RAM, Disk, OS/Kernel), damit Fleet-Diagnose
# nicht mehr jedes Mal manuell per SSH nachgefragt werden muss
# (siehe z.B. Player 667/671-Fälle).
#########################################################

BIN=/home/snowtv/bin
LOG=/var/log/stv.log
MARKER="/tmp/hwinfo_sent"

_log() { echo "$(date '+%Y-%m-%d %H:%M:%S') hwinfo: $*" >> "$LOG"; }

# Bereits in diesem Boot-Zyklus hochgeladen (/tmp wird bei Reboot geleert)
[ -f "$MARKER" ] && exit 0

# ── Netzwerk: MAC/IP/Prefix pro physischem Interface ───────
_net_json() {
    local entries="[]"
    local IFACE MAC IP PFX
    for IFACE in $(ls /sys/class/net/ | grep -vE '^(lo|veth|docker|br-|virbr|wg)'); do
        MAC=$(cat "/sys/class/net/$IFACE/address" 2>/dev/null)
        [ -z "$MAC" ] && continue
        IP=$(ip -o -4 addr show "$IFACE" 2>/dev/null | awk '{print $4}' | head -1 | cut -d/ -f1)
        PFX=$(ip -o -4 addr show "$IFACE" 2>/dev/null | awk '{print $4}' | head -1 | cut -d/ -f2)
        entries=$(echo "$entries" | jq --arg iface "$IFACE" --arg mac "$MAC" \
            --arg ip "${IP:-}" --arg pfx "${PFX:-}" \
            '. += [{"iface":$iface,"mac":$mac,"ip":$ip,"prefix":$pfx}]')
    done
    echo "$entries"
}

GW=$(ip route show default 2>/dev/null | grep -oP 'via \K\S+' | head -1)
DNS=$(grep -oP '^nameserver \K\S+' /etc/resolv.conf 2>/dev/null | paste -sd, -)

# ── Hardware-Identität ──────────────────────────────────────
# DMI (x86/fitlet) zuerst, sonst Device-Tree-Modell (Raspberry Pi) - beide
# ohne root lesbar, swinstall.sh schraenkt sudo am Ende auf shutdown/reboot ein.
MODEL=$(cat /sys/class/dmi/id/product_name 2>/dev/null)
[ -z "$MODEL" ] && MODEL=$(tr -d '\0' < /proc/device-tree/model 2>/dev/null)
VENDOR=$(cat /sys/class/dmi/id/sys_vendor 2>/dev/null)

OS_VERSION=$(cat /etc/debian_version 2>/dev/null)
KERNEL=$(uname -r)
CPU_MODEL=$(lscpu 2>/dev/null | grep -oP '^Model name:\s+\K.+' | head -1)
[ -z "$CPU_MODEL" ] && CPU_MODEL=$(grep -m1 '^model name' /proc/cpuinfo 2>/dev/null | cut -d: -f2 | xargs)
CPU_CORES=$(nproc 2>/dev/null)
RAM_MB=$(awk '/MemTotal/{print int($2/1024)}' /proc/meminfo 2>/dev/null)

# Primäre Disk (erstes nicht-Wechseldatenträger-Blockgerät)
DISK_NAME=$(lsblk -dn -o NAME,RM 2>/dev/null | awk '$2==0{print $1; exit}')
DISK_MODEL=$(lsblk -dn -o MODEL "/dev/$DISK_NAME" 2>/dev/null | xargs)
DISK_SIZE=$(lsblk -dn -o SIZE "/dev/$DISK_NAME" 2>/dev/null | xargs)
read -r DISK_TOTAL DISK_USED DISK_AVAIL <<< "$(df -BG / 2>/dev/null | awk 'NR==2{gsub("G","",$2); gsub("G","",$3); gsub("G","",$4); print $2, $3, $4}')"

ID="$($BIN/getid.sh)"
DOMAIN="$($BIN/getdomain.sh | tr -d "[']")"

# Kein Token → noch nicht freigeschaltet, job.sh ruft naechste Minute erneut auf
TOK="$(cat "$BIN/token" 2>/dev/null)"
[ -z "$TOK" ] && exit 0

NET_JSON="$(_net_json)"

JSON=$(jq -n \
    --arg model   "$MODEL" \
    --arg vendor  "$VENDOR" \
    --arg os      "$OS_VERSION" \
    --arg kernel  "$KERNEL" \
    --arg cpu     "$CPU_MODEL" \
    --argjson cores "${CPU_CORES:-0}" \
    --argjson ram_mb "${RAM_MB:-0}" \
    --arg disk_model "$DISK_MODEL" \
    --arg disk_size  "$DISK_SIZE" \
    --argjson disk_total_gb "${DISK_TOTAL:-0}" \
    --argjson disk_used_gb  "${DISK_USED:-0}" \
    --argjson disk_avail_gb "${DISK_AVAIL:-0}" \
    --arg gw   "${GW:-}" \
    --arg dns  "${DNS:-}" \
    --argjson net "$NET_JSON" \
    '{"hwInfo":{
        model: $model, vendor: $vendor, os: $os, kernel: $kernel,
        cpu: $cpu, cores: $cores, ram_mb: $ram_mb,
        disk: {model: $disk_model, size: $disk_size,
               total_gb: $disk_total_gb, used_gb: $disk_used_gb, avail_gb: $disk_avail_gb},
        gw: $gw, dns: $dns, net: $net
    }}')

HTTP=$(curl -k --connect-timeout 20 --max-time 40 -s -w "%{http_code}" -o /dev/null \
    --data "$JSON" \
    -H "APG-Authorization: ${TOK}" \
    "${DOMAIN}/apg-mp?device=${ID}" \
    --user-agent "apg-mp")

if [ "$HTTP" = "200" ]; then
    touch "$MARKER"
    _log "Upload OK (HTTP $HTTP): $JSON"
else
    _log "Upload fehlgeschlagen (HTTP $HTTP) – job.sh versucht es naechste Minute erneut"
fi

exit 0
