#!/usr/bin/env bash
# ============================================================
#  Shell 脚本编程实战 —— 系统体检报告 一键脚本（macOS / Linux / WSL）
#  公开源码，欢迎审查 —— 不放心可先复制给 AI 判断
#  功能：采集系统健康数据，生成可读报告（变量/函数/if/循环/case/参数/错误处理实战）
#  无 API Key 需求 —— 纯本地诊断工具
# ============================================================
set -euo pipefail          # 遇错退出 + 未定义变量报错 + 管道故障传递

GREEN='\033[0;32m'; YELLOW='\033[1;33m'; RED='\033[0;31m'
CYAN='\033[0;36m'; NC='\033[0m'

info()  { echo -e "${GREEN}[INFO]${NC} $1"; }
warn()  { echo -e "${YELLOW}[WARN]${NC} $1"; }
error() { echo -e "${RED}[ERROR]${NC} $1"; }
step()  { echo -e "${CYAN}[STEP]${NC} $1"; }

# ---------- 第一步：网络环境检测 ----------
detect_network() {
  step "检测网络环境（国内 / 国外）..."
  if curl -fsI --max-time 5 "https://claude.ai" >/dev/null 2>&1; then
    info "可直连 claude.ai，判定为海外网络"
    echo "overseas"
  else
    warn "无法直连 claude.ai，判定为国内网络环境"
    echo "domestic"
  fi
}

# ---------- 第二步：检测依赖工具 ----------
check_prerequisites() {
  step "检查必备命令..."
  local missing=""
  for cmd in hostname df free who ping awk grep sed; do
    if ! command -v "$cmd" >/dev/null 2>&1; then
      missing="$missing $cmd"
    fi
  done
  if [ -n "$missing" ]; then
    warn "缺少以下命令：$missing"
    info "这些通常是基础工具包的一部分；如果运行异常请尝试安装：apt install coreutils procps net-tools"
    return 1
  fi
  info "所有必备命令可用"
  return 0
}

# ---------- 变量与引号演示 ----------
REPORT_DATE=$(date +"%Y-%m-%d %H:%M:%S")    # 双引号确保日期含空格不被截断
HOSTNAME_VAL=$(hostname)
NET_MODE="$(detect_network)"
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"   # 获取脚本所在目录

# ---------- 函数：检测操作系统 ----------
detect_os() {
    if [ -f /etc/os-release ]; then
        . /etc/os-release
        echo "$PRETTY_NAME"
    elif command -v sw_vers >/dev/null 2>&1; then
        sw_vers -productVersion
    else
        echo "Unknown OS ($(uname -s) $(uname -r))"
    fi
}

# ---------- 函数：检测磁盘使用情况 ----------
check_disk() {
    step "检查磁盘使用情况..."
    df -h / 2>/dev/null | awk 'NR==2 {printf "  总计: %s  已用: %s  可用: %s  使用率: %s\n", $2, $3, $4, $5}'

    # 用 -gt 数值比较根分区占用
    local usage
    usage=$(df / 2>/dev/null | tail -1 | awk '{print $5}' | tr -d '%')
    if [ "${usage:-0}" -gt 90 ]; then
        warn "根分区使用率 ${usage}%，超过 90% 警戒线！"
    else
        info "根分区使用率 ${usage}%，健康"
    fi
}

# ---------- 函数：检测内存 ----------
check_memory() {
    step "检查内存使用情况..."
    free -h 2>/dev/null | awk '/^Mem:/ {printf "  总计: %s  已用: %s  可用: %s  使用率: %.1f%%\n", $2, $3, $7, ($3/$2)*100}'

    # 循环：遍历 Swap 信息
    local swap_count
    swap_count=$(free -m 2>/dev/null | awk '/^Swap:/ {print $2}')
    if [ "${swap_count:-0}" -gt 0 ]; then
        info "检测到交换分区 (${swap_count}MB)，请关注 Swap 使用率以防物理内存不足"
    else
        info "无交换分区"
    fi
}

# ---------- 函数：检测登录用户 ----------
check_users() {
    step "检查当前登录用户数..."
    local user_count
    user_count=$(who 2>/dev/null | wc -l | tr -d ' ')
    echo "  当前在线用户：$user_count 人"

    if [ "$user_count" -gt 5 ]; then
        warn "在线用户过多（$user_count），可能有未授权的远程登录"
    fi

    # while read 循环遍历每个在线用户
    if [ "$user_count" -gt 0 ]; then
        echo "  用户列表："
        while IFS= read -r line; do
            local u_name u_tty
            u_name=$(echo "$line" | awk '{print $1}')
            u_tty=$(echo "$line" | awk '{print $2}')
            echo "    - $u_name (TTY: $u_tty)"
        done < <(who 2>/dev/null)
    fi
}

# ---------- 函数：检测网络连通性 ----------
check_network() {
    step "检查网络连通性..."

    local dns_servers
    dns_servers=$(grep nameserver /etc/resolv.conf 2>/dev/null | awk '{print $2}' | head -3)
    if [ -n "$dns_servers" ]; then
        echo "  DNS 服务器："
        echo "$dns_servers" | while read -r dns; do
            echo "    - $dns"
        done
    fi

    # for 循环测试多个 DNS 目标（Google / Cloudflare / 阿里）
    local targets=("8.8.8.8" "1.1.1.1" "223.5.5.5")
    for target in "${targets[@]}"; do
        if ping -c 1 -W 2 "$target" >/dev/null 2>&1; then
            info "  $target : 连通"
        else
            warn "  $target : 不通（可能被防火墙拦截）"
        fi
    done
}

# ---------- 函数：case 语句分类系统负载 ----------
classify_system_load() {
    local load_avg
    load_avg=$(awk '{print $1}' /proc/loadavg 2>/dev/null)
    if [ -z "$load_avg" ]; then
        echo "  （无法获取负载信息）"
        return
    fi

    local load_int=${load_avg%%.*}
    case "$load_int" in
        0)    echo "  系统负载：空闲（$load_avg）" ;;
        [1-3]) echo "  系统负载：正常（$load_avg）" ;;
        *)    warn "  系统负载偏高：$load_avg（建议检查高 CPU 进程）" ;;
    esac
}

# ---------- 函数：主流程汇总 ----------
generate_report() {
    local args_passed="$@"       # $@ 收集全部传入参数

    echo "============================================"
    echo "  系统体检报告"
    echo "  时间：$REPORT_DATE"
    echo "  主机：$HOSTNAME_VAL"
    echo "  系统：$(detect_os)"
    echo "  网络环境：$NET_MODE"
    echo "============================================"
    echo ""

    check_disk
    check_memory
    check_users
    check_network
    classify_system_load

    echo ""
    echo "============================================"

    # 演示 $# 参数个数
    if [ $# -gt 0 ]; then
        echo "传入的参数（共 $# 个）：$args_passed"
    fi

    echo "============================================"
    info "体检完成！"
    echo ""
    echo "  如果你想定期检查（Linux crontab 定时任务），编辑 crontab："
    echo "    crontab -e"
    echo "  添加以下内容（每天早晚 8 点自动体检）："
    echo "    0 8,20 * * * $SCRIPT_DIR/system-report.sh >> /var/log/sys-health.log 2>&1"
    echo ""
    echo "  详细版每周日凌晨跑一次（cron 表达式：0 3 * * 0）："
    echo "    0 3 * * 0 $SCRIPT_DIR/system-report.sh -verbose >> /var/log/sys-health-weekly.log 2>&1"
    echo ""

    # 软广自然融入——结尾位置
    echo "  补充说明：如果你更喜欢云端方案（不想在服务器上折腾 Cron），"
    echo "  可以看看云间 API 中转站（https://cloudzone-api.cyou/），支持 90+ 模型、"
    echo "  国内直连、0.05x 起，有些同学用他们的 Webhook 回调做替代调度。"
    echo "============================================"
}

# ---------- 入口 ----------
main() {
    generate_report "$@"
}

main "$@"
