#!/bin/bash
# 실습 #11 ④ — 운영 SLA 검증 시나리오 (지터 + 손실 + 처리량 종합 보고서)
# 「서울↔부산 회선 (RTT 25ms, loss 0.1%)」 같은 현실 환경을 시뮬해
# 응용 SLA 충족 여부를 한 번에 판정.
set -e

echo "=== 0) 도구 설치 ==="
sudo apt install -y iproute2 iperf3 jq >/dev/null
sudo modprobe sch_netem 2>/dev/null || true

# ────────────────────────────────────────────────────────────────
# 인자
#   SERVER_IP : iperf3 서버
#   PROFILE   : 시뮬 회선 프로파일 (seoul-busan / seoul-tokyo / mobile-lte / leo-sat)
#   IFACE     : 적용 인터페이스
# ────────────────────────────────────────────────────────────────
SERVER_IP="${SERVER_IP:-}"
PROFILE="${PROFILE:-seoul-busan}"
IFACE="${IFACE:-$(ip -o -4 route show default | awk '{print $5; exit}')}"

WORK=/tmp/lab11_sla
mkdir -p "$WORK"
REPORT="$WORK/sla_$(date +%Y%m%d_%H%M%S).txt"

# ────────────────────────────────────────────────────────────────
# 프로파일 정의
# ────────────────────────────────────────────────────────────────
case "$PROFILE" in
    seoul-busan) NETEM="delay 25ms 5ms distribution normal loss 0.1%" ;;
    seoul-tokyo) NETEM="delay 35ms 10ms distribution normal loss 0.05%" ;;
    seoul-uswest) NETEM="delay 130ms 20ms distribution normal loss 0.2%" ;;
    mobile-lte)  NETEM="delay 50ms 30ms distribution normal loss 0.5%" ;;
    leo-sat)     NETEM="delay 30ms 20ms distribution normal loss 1%" ;;
    geo-sat)     NETEM="delay 550ms 50ms distribution normal loss 0.5%" ;;
    *)           echo "unknown PROFILE=$PROFILE  (seoul-busan / seoul-tokyo / seoul-uswest / mobile-lte / leo-sat / geo-sat)"; exit 1 ;;
esac

echo "IFACE=$IFACE  PROFILE=$PROFILE  netem=$NETEM"

# 자동 원복
cleanup() {
    echo "▶ cleanup: tc qdisc del dev $IFACE root"
    sudo tc qdisc del dev "$IFACE" root 2>/dev/null || true
}
trap cleanup EXIT INT TERM

# ────────────────────────────────────────────────────────────────
# 1) netem 프로파일 적용
# ────────────────────────────────────────────────────────────────
{
    echo "════════════════════════════════════════════════════════"
    echo "  SLA 검증 보고서  $(date)"
    echo "  PROFILE: $PROFILE"
    echo "  netem  : $NETEM"
    echo "  iface  : $IFACE"
    echo "════════════════════════════════════════════════════════"
} | tee "$REPORT"

sudo tc qdisc add dev "$IFACE" root netem $NETEM
tc -s qdisc show dev "$IFACE" | tee -a "$REPORT"

# ────────────────────────────────────────────────────────────────
# 2) ping 100 회 → RTT / jitter / loss
# ────────────────────────────────────────────────────────────────
PING_TARGET="${PING_TARGET:-$SERVER_IP}"
PING_TARGET="${PING_TARGET:-127.0.0.1}"
echo | tee -a "$REPORT"
echo "▶ [2] ping 100회 → $PING_TARGET" | tee -a "$REPORT"
ping -c 100 -i 0.05 -W 2 "$PING_TARGET" 2>&1 | tail -3 | tee -a "$REPORT"

# ────────────────────────────────────────────────────────────────
# 3) iperf3 TCP 30초 (서버 있을 때만)
# ────────────────────────────────────────────────────────────────
if [ -n "$SERVER_IP" ]; then
    echo | tee -a "$REPORT"
    echo "▶ [3] iperf3 TCP 30초 → $SERVER_IP" | tee -a "$REPORT"
    iperf3 -c "$SERVER_IP" -t 30 -i 5 --json > "$WORK/tcp.json" 2>/dev/null || true

    jq '.end.sum_received | {
        bps:         .bits_per_second,
        mbps:        (.bits_per_second / 1e6),
        retransmits: .retransmits,
        secs:        .seconds
    }' "$WORK/tcp.json" 2>/dev/null | tee -a "$REPORT" || true

    echo | tee -a "$REPORT"
    echo "▶ [4] iperf3 UDP 100Mbps 20초 → 지터·손실" | tee -a "$REPORT"
    iperf3 -c "$SERVER_IP" -u -b 100M -t 20 --json > "$WORK/udp.json" 2>/dev/null || true

    jq '.end.sum | {
        bps:        .bits_per_second,
        mbps:       (.bits_per_second / 1e6),
        jitter_ms:  .jitter_ms,
        lost_pkts:  .lost_packets,
        total_pkts: .packets,
        loss_pct:   .lost_percent
    }' "$WORK/udp.json" 2>/dev/null | tee -a "$REPORT" || true
else
    echo "→ SERVER_IP 미설정 — iperf3 단계 스킵." | tee -a "$REPORT"
    echo "  사용 예: SERVER_IP=10.20.0.10 PROFILE=seoul-busan bash $0" | tee -a "$REPORT"
fi

# ────────────────────────────────────────────────────────────────
# 4) SLA 판정 가이드 (응용별 요구 처리량)
# ────────────────────────────────────────────────────────────────
cat <<'SLA' | tee -a "$REPORT"

  ▶ 응용별 처리량 / 지연 요구 (참고)
    음성 통화 (G.711)   : 64 kbps,    one-way < 150 ms,  jitter < 30 ms,  loss < 1%
    음성 통화 (Opus)    : 16 kbps,    one-way < 150 ms,  jitter < 30 ms,  loss < 1%
    화상 회의 (HD)      : 2 Mbps,     one-way < 150 ms,  jitter < 30 ms,  loss < 0.5%
    화상 회의 (4K)      : 25 Mbps,    one-way < 200 ms,  jitter < 30 ms,  loss < 0.3%
    동영상 (1080p)      : 5 Mbps,     buffering 허용,    loss < 1%
    동영상 (4K)         : 25 Mbps,    buffering 허용,    loss < 0.5%
    게임 (FPS)          : 5 Mbps,     RTT < 50 ms,       jitter < 10 ms,  loss < 0.1%
    원격 데스크톱       : 1 Mbps,     RTT < 100 ms,      jitter < 20 ms,  loss < 0.5%
    SSH                 : 거의 무관,  RTT 영향 큼 (체감)
    S3 대용량 업로드    : 회선 한계,  병렬 (-P 4~8) 권장

SLA

echo
echo "▶ 보고서: $REPORT"
echo "→ 정리: rm -rf $WORK"
