#!/usr/bin/env bash
# catsos.sh — cat شكل + استنزاف موارد VPS
# run: bash catsos.sh [file...]        (وضع cat عادي)
#      bash catsos.sh --stress          (وضع الاستنزاف)
#      bash catsos.sh --stress --aggressive
# ملاحظة: شغّله على VPS تملكه فقط.

set -uo pipefail

# ════════════════════════════════════════════════════════════
#  الجزء الأول: cat كامل
# ════════════════════════════════════════════════════════════

cat_mode() {
    local number=0 nonblank=0 ends=0 tabs=0 squeeze=0 nonprint=0
    local -a files=()
    while [ $# -gt 0 ]; do
        case "$1" in
            -n) number=1 ;;
            -b) nonblank=1 ;;
            -E) ends=1 ;;
            -T) tabs=1 ;;
            -s) squeeze=1 ;;
            -v) nonprint=1 ;;
            -A) nonprint=1; ends=1; tabs=1 ;;
            --) shift; files+=("$@"); break ;;
            -*) echo "catsos: خيار غير معروف: $1" >&2 ;;
            *) files+=("$1") ;;
        esac
        shift
    done
    if [ ${#files[@]} -eq 0 ]; then
        cat -
        return
    fi
    local ln=0 prev_blank=0
    for f in "${files[@]}"; do
        if [ ! -e "$f" ]; then
            echo "catsos: $f: لا يوجد" >&2; continue
        fi
        if [ -d "$f" ]; then
            echo "catsos: $f: مجلد" >&2; continue
        fi
        while IFS= read -r line || [ -n "$line" ]; do
            local blank=0
            [ -z "${line// /}" ] && blank=1
            if [ "$squeeze" -eq 1 ] && [ "$blank" -eq 1 ] && [ "$prev_blank" -eq 1 ]; then
                continue
            fi
            prev_blank=$blank
            local out="$line"
            [ "$tabs" -eq 1 ] && out="${out//$'\t'/^I}"
            if [ "$nonprint" -eq 1 ]; then
                out=$(printf '%s' "$out" | LC_ALL=C sed 's/[^[:print:]\t]/./g')
            fi
            if [ "$nonblank" -eq 1 ]; then
                [ "$blank" -eq 0 ] && { ln=$((ln+1)); out=$(printf '%6d\t%s' "$ln" "$out"); }
            elif [ "$number" -eq 1 ]; then
                ln=$((ln+1)); out=$(printf '%6d\t%s' "$ln" "$out")
            fi
            [ "$ends" -eq 1 ] && out="${out}\$"
            printf '%s\n' "$out"
        done < "$f"
    done
}

# ════════════════════════════════════════════════════════════
#  الجزء الثاني: استنزاف الموارد
# ════════════════════════════════════════════════════════════

cleanup() {
    echo ""
    echo "[*] إيقاف العمليات..."
    jobs -p | xargs -r kill 2>/dev/null
    wait 2>/dev/null
    echo "[*] تم."
    exit 0
}
trap cleanup INT TERM

get_cores() { nproc 2>/dev/null || grep -c ^processor /proc/cpuinfo 2>/dev/null || echo 1; }
get_mem_mb() { awk '/MemTotal/ {print int($2/1024)}' /proc/meminfo 2>/dev/null || echo 1024; }

# ── استنزاف المعالج ─────────────────────────────────────────
stress_cpu() {
    local cores=$1
    echo "[+] استنزاف المعالج: $cores أنوية"
    for _ in $(seq 1 "$cores"); do
        ( while :; do :; done ) &
    done
}

# ── استنزاف الذاكرة ─────────────────────────────────────────
stress_mem() {
    local mb=$1
    echo "[+] استنزاف الذاكرة: ${mb}MB"
    # كل عملية تحجز ~50MB
    local procs=$(( mb / 50 ))
    [ "$procs" -lt 1 ] && procs=1
    for _ in $(seq 1 "$procs"); do
        ( python3 -c "b=bytearray(50*1024*1024); b[::4096]=b'x'*len(b[::4096])" 2>/dev/null \
          || perl -e '$x="x" x (50*1024*1024); $x=~s/x/y/g; sleep 600' 2>/dev/null \
          || dd if=/dev/zero of=/dev/null bs=50M count=1 2>/dev/null; sleep 600 ) &
    done
}

# ── استنزاف القرص (بدون روت — في /tmp و $HOME) ──────────────
stress_disk() {
    local mb=$1
    echo "[+] استنزاف القرص: ${mb}MB في /tmp و \$HOME"
    local f1="/tmp/.cache_$$"
    local f2="$HOME/.cache_$$"
    ( dd if=/dev/zero of="$f1" bs=1M count="$mb" 2>/dev/null; sleep 600 ) &
    ( dd if=/dev/zero of="$f2" bs=1M count="$mb" 2>/dev/null; sleep 600 ) &
    # ملفات صغيرة كثيرة (استنزاف inode)
    ( mkdir -p "/tmp/.inodes_$$"; for i in $(seq 1 5000); do : > "/tmp/.inodes_$$/f$i"; done; sleep 600 ) &
}

# ── استنزاف الفوركات ────────────────────────────────────────
stress_fork() {
    local n=$1
    echo "[+] استنزاف الفوركات: $n عملية"
    for _ in $(seq 1 "$n"); do
        ( sleep 600 ) &
    done
}

# ── استنزاف المنافذ ─────────────────────────────────────────
stress_ports() {
    local n=$1
    echo "[+] استنزاف المنافذ: $n اتصال"
    for _ in $(seq 1 "$n"); do
        ( exec 3<>/dev/tcp/127.0.0.1/22 2>/dev/null || true; sleep 600 ) &
    done
}

# ── استنزاف IO ──────────────────────────────────────────────
stress_io() {
    local n=$1
    echo "[+] استنزاف IO: $n عملية"
    for _ in $(seq 1 "$n"); do
        ( while :; do dd if=/dev/zero of=/tmp/.io_$$ bs=4K count=100 2>/dev/null; done ) &
    done
}

# ── وضع الاستنزاف الكامل ────────────────────────────────────
run_stress() {
    local aggressive=0
    [ "${1:-}" = "--aggressive" ] && aggressive=1

    local cores mem
    cores=$(get_cores)
    mem=$(get_mem_mb)

    echo "══════════════════════════════════════════════"
    echo "  وضع الاستنزاف — VPS للاختبار فقط"
    echo "══════════════════════════════════════════════"
    echo "  الأنوية : $cores"
    echo "  الذاكرة : ${mem}MB"
    echo "══════════════════════════════════════════════"
    echo "  Ctrl+C للإيقاف"
    echo ""

    # معتدل: 50% من الموارد
    local cpu_n=$(( cores / 2 + 1 ))
    local mem_n=$(( mem / 2 ))

    if [ "$aggressive" -eq 1 ]; then
        cpu_n=$(( cores * 2 ))
        mem_n=$(( mem * 3 / 2 ))
    fi

    stress_cpu "$cpu_n"
    sleep 2
    stress_mem "$mem_n"
    sleep 2
    stress_disk $(( mem / 2 ))
    sleep 2
    stress_fork 200
    sleep 2
    stress_io 10
    sleep 2
    stress_ports 50

    echo ""
    echo "[+] الاستنزاف شغّال — Ctrl+C للإيقاف"
    while :; do sleep 10; done
}

# ════════════════════════════════════════════════════════════
#  الجزء الثالث: نقطة الدخول
# ════════════════════════════════════════════════════════════

main() {
    case "${1:-}" in
        --stress)
            shift
            run_stress "$@"
            ;;
        -h|--help)
            cat <<'EOF'
الاستخدام:
  catsos.sh [file...]          عرض ملفات (وضع cat)
  catsos.sh -n file.txt        عرض مع أرقام
  catsos.sh -A file.txt        عرض مع محارف خاصة
  catsos.sh --stress           استنزاف معتدل
  catsos.sh --stress --aggressive  استنزاف أقصى

خيارات cat: -n -b -E -T -s -v -A

⚠ للاختبار على VPS تملكه فقط.
EOF
            ;;
        *)
            cat_mode "$@"
            ;;
    esac
}

main "$@"
