#!/usr/bin/env bash
# xmhls-sysinfo 1.0.0 — 超频 / 低延迟服务器硬件与系统盘点（只读）
#
# 用法: sudo bash xmhls-sysinfo-1.0.0.sh [-o 文件] [-h]
#   -o FILE   同时把报告保存到 FILE
#   -h        显示帮助
# 说明: 只读取系统信息，不做任何修改。缺少的工具标注 NA 后继续。
#       dmidecode / ipmitool / nvme 等信息需要 root。
#
# MIT License · Copyright (c) 2026 西门华莱硕投资咨询有限公司 · https://xmhls.com/guide/#script-sysinfo
set -uo pipefail
VERSION=1.0.0
OUT=""

usage() { sed -n '2,9p' "$0" | sed 's/^# \{0,1\}//'; }
while [ $# -gt 0 ]; do
    case "$1" in
        -o) OUT="${2:?-o 需要文件名}"; shift 2 ;;
        -h|--help) usage; exit 0 ;;
        *) echo "未知参数: $1" >&2; usage >&2; exit 2 ;;
    esac
done

have() { command -v "$1" >/dev/null 2>&1; }
is_root() { [ "$(id -u)" -eq 0 ]; }
section() { printf '\n===== %s =====\n' "$1"; }
na() { echo "  NA（$1）"; }

report() {
    echo "xmhls-sysinfo $VERSION · $(date -u '+%F %T UTC') · host=$(hostname) · user=$(id -un)"
    is_root || echo "提示：非 root 运行，主板 / 内存条 / BMC / NVMe 等信息可能缺失"

    section "1. 操作系统与内核"
    grep -E '^(PRETTY_NAME|VERSION_ID)=' /etc/os-release 2>/dev/null || na "/etc/os-release 不可读"
    uname -a
    echo "启动参数: $(cat /proc/cmdline)"
    echo "运行时长: $(uptime -p 2>/dev/null || uptime)"

    section "2. 主板与 BIOS"
    if is_root && have dmidecode; then
        echo "厂商 / 型号: $(dmidecode -s system-manufacturer) / $(dmidecode -s system-product-name)"
        echo "主板: $(dmidecode -s baseboard-manufacturer) $(dmidecode -s baseboard-product-name)"
        echo "BIOS: $(dmidecode -s bios-vendor) $(dmidecode -s bios-version)（$(dmidecode -s bios-release-date)）"
    else
        for f in sys_vendor product_name board_vendor board_name bios_vendor bios_version bios_date; do
            printf '  %-14s %s\n' "$f" "$(cat "/sys/class/dmi/id/$f" 2>/dev/null || echo NA)"
        done
    fi

    section "3. CPU"
    if have lscpu; then
        lscpu | grep -E '^(Architecture|Model name|Socket|Core|Thread|CPU\(s\)|On-line|NUMA node|CPU max MHz|CPU min MHz|L1d|L2|L3|Vendor ID|Virtualization|Flags)' \
              | sed 's/^Flags:.*$/Flags: （略，见 \/proc\/cpuinfo）/'
    else
        na "未安装 lscpu"
    fi
    echo "微码: $(grep -m1 '^microcode' /proc/cpuinfo | awk '{print $3}')"
    echo "调频驱动 / 调速器: $(cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_driver 2>/dev/null || echo NA) / $(cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor 2>/dev/null || echo NA)"
    echo "SMT: $(cat /sys/devices/system/cpu/smt/control 2>/dev/null || echo NA)"
    echo "隔离核: $(cat /sys/devices/system/cpu/isolated 2>/dev/null || echo NA)    nohz_full: $(cat /sys/devices/system/cpu/nohz_full 2>/dev/null || echo NA)"
    echo "当前频率 MHz（按逻辑核）: $(awk -F: '/^cpu MHz/{printf "%.0f ", $2}' /proc/cpuinfo)"

    section "4. 内存"
    free -h
    if is_root && have dmidecode; then
        echo "--- 内存条 ---"
        dmidecode -t 17 | awk -F': ' '
            /^Memory Device/ {if (sz != "" && sz !~ /No Module/) printf "  %-10s %-10s %-6s %-12s %-14s %s %s\n", loc, sz, ty, sp, cs, mf, pn; sz=loc=ty=sp=cs=mf=pn=""}
            /^\tSize:/ {sz=$2} /^\tLocator:/ {loc=$2} /^\tType:/ {ty=$2} /^\tSpeed:/ {sp=$2}
            /^\tConfigured Memory Speed:/ {cs=$2} /^\tManufacturer:/ {mf=$2} /^\tPart Number:/ {pn=$2}
            END {if (sz != "" && sz !~ /No Module/) printf "  %-10s %-10s %-6s %-12s %-14s %s %s\n", loc, sz, ty, sp, cs, mf, pn}'
        echo "ECC: $(dmidecode -t 16 | awk -F': ' '/Error Correction Type/{print $2; exit}')"
    fi
    if [ -d /sys/devices/system/edac/mc ]; then
        for mc in /sys/devices/system/edac/mc/mc*; do
            [ -d "$mc" ] && echo "EDAC $(basename "$mc"): 可纠正=$(cat "$mc/ce_count") 不可纠正=$(cat "$mc/ue_count")"
        done
    else
        na "未加载 EDAC 驱动（无法读取 ECC 纠错计数）"
    fi

    section "5. NUMA 拓扑"
    if have numactl; then numactl -H; elif have lscpu; then lscpu | grep -i numa; else na "未安装 numactl / lscpu"; fi

    section "6. PCIe 网卡与加速卡"
    if have lspci; then
        lspci -nn | grep -iE 'ethernet|network|infiniband|processing accelerators|co-processor|fpga|xilinx|altera|solarflare|exablaze|bittware|napatech' \
            || echo "  （未发现网卡 / 加速卡）"
    else
        na "未安装 lspci（pciutils）"
    fi

    section "7. 网络接口"
    ip -br link
    for dev in /sys/class/net/*; do
        i="$(basename "$dev")"
        [ -e "$dev/device" ] || continue
        echo "--- $i（NUMA 节点 $(cat "$dev/device/numa_node" 2>/dev/null || echo NA)）---"
        if have ethtool; then
            ethtool -i "$i" 2>/dev/null | grep -E '^(driver|version|firmware-version|bus-info):'
            ethtool "$i" 2>/dev/null | grep -E 'Speed:|Link detected:'
        else
            na "未安装 ethtool"
        fi
    done

    section "8. 存储"
    lsblk -o NAME,SIZE,TYPE,MODEL,ROTA,MOUNTPOINTS 2>/dev/null || lsblk
    if is_root && have nvme; then nvme list 2>/dev/null; fi

    section "9. 时钟同步"
    timedatectl 2>/dev/null | grep -E 'Time zone|synchronized|NTP service' || na "timedatectl 不可用"
    if have chronyc; then chronyc tracking 2>/dev/null | grep -E 'Reference ID|System time|Last offset|RMS offset'; fi
    pgrep -a ptp4l 2>/dev/null || true
    pgrep -a phc2sys 2>/dev/null || true
    echo "时钟源: $(cat /sys/devices/system/clocksource/clocksource0/current_clocksource 2>/dev/null || echo NA)"

    section "10. 温度与 BMC"
    if have sensors; then sensors 2>/dev/null | grep -E '°C' | head -n 24; else na "未安装 lm-sensors"; fi
    if is_root && have ipmitool; then
        ipmitool sdr type Temperature 2>/dev/null | head -n 24
        echo "--- BMC 事件日志（最近 10 条）---"
        ipmitool sel elist 2>/dev/null | tail -n 10
    fi

    printf '\n== 完成 ==\n'
}

if [ -n "$OUT" ]; then
    report | tee "$OUT"
    echo "报告已保存: $OUT"
else
    report
fi
