#!/bin/bash
# validate-fixes.sh - READ-ONLY validation of all applied tunings.
# Does NOT reboot, shutdown VMs, or modify anything.
set -uo pipefail
SSH_OPTS=(-o BatchMode=yes -o ConnectTimeout=8 -o StrictHostKeyChecking=accept-new)

HOSTS=(pfv-tsys1 pfv-tsys3 pfv-tsys6 pfv-tsys7 pfv-tsys9)

echo "==================================================================="
echo " READ-ONLY VALIDATION — $(date)"
echo "==================================================================="
echo ""

for HOST in "${HOSTS[@]}"; do
    echo "================================================================"
    echo "[$HOST]"
    echo "================================================================"

    if ! ssh "${SSH_OPTS[@]}" "root@$HOST" 'echo ok' >/dev/null 2>&1; then
        echo "  UNREACHABLE"
        echo ""
        continue
    fi

    ssh "${SSH_OPTS[@]}" "root@$HOST" '
        pass=0; fail=0
        check() {
            local label="$1" actual="$2" expected="$3"
            if [ "$actual" = "$expected" ]; then
                printf "  [OK]   %-30s %s\n" "$label" "$actual"
                pass=$((pass+1))
            else
                printf "  [FAIL] %-30s got=%s want=%s\n" "$label" "$actual" "$expected"
                fail=$((fail+1))
            fi
        }

        # 1. CPU governor
        gov=$(cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor 2>/dev/null || echo "n/a")
        if [ "$gov" = "n/a" ]; then
            printf "  [SKIP] %-30s %s\n" "CPU governor" "(no cpufreq driver — OK for server BIOS)"
        else
            check "CPU governor" "$gov" "performance"
        fi

        # 2. vm.swappiness
        swap=$(sysctl -n vm.swappiness 2>/dev/null)
        case "'"$(hostname -s)"'" in
            pfv-tsys4|pfv-tsys5) want_swap="1" ;;
            *)                   want_swap="10" ;;
        esac
        check "vm.swappiness" "$swap" "$want_swap"

        # 3. TCP congestion control
        cc=$(sysctl -n net.ipv4.tcp_congestion_control 2>/dev/null)
        check "tcp_congestion_control" "$cc" "bbr"

        # 4. default_qdisc (paired with BBR)
        qd=$(sysctl -n net.core.default_qdisc 2>/dev/null)
        check "net.core.default_qdisc" "$qd" "fq"

        # 5. tuned profile
        if command -v tuned-adm >/dev/null 2>&1; then
            tuned=$(tuned-adm active 2>/dev/null | awk -F: "/Current active/{gsub(/^[ \t]+/,\"\",\$2); print \$2}")
            case "'"$(hostname -s)"'" in
                pfv-tsys4|pfv-tsys5) want_tuned="throughput-performance" ;;
                *)                   want_tuned="virtual-host" ;;
            esac
            check "tuned-adm profile" "$tuned" "$want_tuned"
        else
            printf "  [FAIL] %-30s not installed\n" "tuned-adm"
            fail=$((fail+1))
        fi

        # 6. bond0 hash policy (if bond exists)
        if [ -r /proc/net/bonding/bond0 ]; then
            hash=$(grep "Transmit Hash" /proc/net/bonding/bond0 2>/dev/null | awk "{print \$4}")
            check "bond0 xmit_hash_policy" "$hash" "layer3+4"
            ports=$(grep "Number of ports" /proc/net/bonding/bond0 2>/dev/null | awk "{print \$4}")
            printf "  [INFO] %-30s %s ports active\n" "bond0 LACP ports" "$ports"
        else
            printf "  [SKIP] %-30s %s\n" "bond0 hash" "(no bond0 — single NIC host)"
        fi

        # 7. NFS mount options (nconnect + noatime)
        nfs_first=$(nfsstat -m 2>/dev/null | head -3 | tail -1)
        if echo "$nfs_first" | grep -q "nconnect=4"; then
            printf "  [OK]   %-30s nconnect=4 active\n" "NFS nconnect"
            pass=$((pass+1))
        elif echo "$nfs_first" | grep -q "relatime"; then
            printf "  [FAIL] %-30s still relatime (needs reboot/mount)\n" "NFS nconnect"
            fail=$((fail+1))
        elif [ -z "$nfs_first" ]; then
            printf "  [WARN] %-30s no NFS mounts (lazy — start a VM)\n" "NFS nconnect"
        else
            printf "  [FAIL] %-30s unexpected: %s\n" "NFS nconnect" "$nfs_first"
            fail=$((fail+1))
        fi

        if echo "$nfs_first" | grep -q "noatime"; then
            printf "  [OK]   %-30s noatime active\n" "NFS noatime"
            pass=$((pass+1))
        elif [ -n "$nfs_first" ]; then
            printf "  [FAIL] %-30s not noatime\n" "NFS noatime"
            fail=$((fail+1))
        fi

        # 8. NFS TCP connection count
        nfs_conns=$(ss -tn state established "( dport = :2049 )" 2>/dev/null | tail -n +2 | wc -l)
        if [ "$nfs_conns" -ge 8 ]; then
            printf "  [OK]   %-30s %s connections\n" "NFS TCP conns" "$nfs_conns"
            pass=$((pass+1))
        elif [ "$nfs_conns" -gt 0 ]; then
            printf "  [WARN] %-30s %s (expect 8 with nconnect=4)\n" "NFS TCP conns" "$nfs_conns"
        else
            printf "  [WARN] %-30s 0 (lazy mounts — start a VM)\n" "NFS TCP conns"
        fi

        # 9. sysctl persistence
        if [ -r /etc/sysctl.d/99-perfopt.conf ]; then
            printf "  [OK]   %-30s /etc/sysctl.d/99-perfopt.conf\n" "sysctl persistence"
            pass=$((pass+1))
        else
            printf "  [FAIL] %-30s missing\n" "sysctl persistence"
            fail=$((fail+1))
        fi

        # 10. Observability packages
        for cmd in sar jq numactl nvme mtr bmon; do
            if ! command -v "$cmd" >/dev/null 2>&1; then
                printf "  [FAIL] %-30s not installed\n" "obs: $cmd"
                fail=$((fail+1))
            fi
        done
        if command -v sar >/dev/null 2>&1 && command -v jq >/dev/null 2>&1 && \
           command -v numactl >/dev/null 2>&1 && command -v nvme >/dev/null 2>&1 && \
           command -v mtr >/dev/null 2>&1 && command -v bmon >/dev/null 2>&1; then
            printf "  [OK]   %-30s all installed\n" "observability packages"
            pass=$((pass+1))
        fi

        # 11. Failed services
        failed_count=$(systemctl --failed --no-legend 2>/dev/null | wc -l)
        if [ "$failed_count" = "0" ]; then
            printf "  [OK]   %-30s none\n" "failed services"
            pass=$((pass+1))
        else
            printf "  [FAIL] %-30s %s failed:\n" "failed services" "$failed_count"
            systemctl --failed --no-legend 2>/dev/null | sed "s/^/         /"
            fail=$((fail+1))
        fi

        # 12. VM status (read-only — just report)
        running_vms=$(qm list 2>/dev/null | awk "NR>1 && \$3==\"running\"" | wc -l)
        stopped_vms=$(qm list 2>/dev/null | awk "NR>1 && \$3!=\"running\"" | wc -l)
        printf "  [INFO] %-30s %s running, %s stopped\n" "VM status" "$running_vms" "$stopped_vms"

        # 13. uptime
        printf "  [INFO] %-30s %s\n" "uptime" "$(uptime | sed "s/.*up //" | sed "s/,.*//")"

        echo ""
        echo "  RESULT: $pass passed, $fail failed"
    '
    echo ""
done

echo "==================================================================="
echo " SUMMARY"
echo "==================================================================="
