#!/bin/bash
# ============================================================
# GUARDiA SM | search_solr_sm.sh
# 대상: Apache Solr (7.x / 8.x / 9.x)
# 파라미터: SOLR_HOME=/opt/solr SOLR_HOST=localhost SOLR_PORT=8983
#           SOLR_USER=solr SOLR_PASS=SolrRocks
#           QUERY_TIME_WARN=1000
# ============================================================
set -euo pipefail
SOLR_HOME=${SOLR_HOME:-/opt/solr}
SOLR_HOST=${SOLR_HOST:-localhost}
SOLR_PORT=${SOLR_PORT:-8983}
SOLR_USER=${SOLR_USER:-""}
SOLR_PASS=${SOLR_PASS:-""}
QUERY_TIME_WARN=${QUERY_TIME_WARN:-1000}
SOLR_BASE="http://${SOLR_HOST}:${SOLR_PORT}"
OK="[OK]"; WARN="[WARN]"; CRIT="[CRIT]"
SEP="─────────────────────────────────────────"
RESULT=0

_solr() {
    local URL="$1"
    local AUTH=""
    [ -n "$SOLR_USER" ] && AUTH="-u ${SOLR_USER}:${SOLR_PASS}"
    curl -sk --max-time 10 $AUTH "${SOLR_BASE}${URL}" 2>/dev/null
}

echo "======================================================"
echo " GUARDiA SM 점검 | Apache Solr | $(hostname -s)"
echo " 점검 시각: $(date '+%Y-%m-%d %H:%M:%S %Z')"
echo "======================================================"

# ── 1. 프로세스 ───────────────────────────────────────────
echo; echo "[$SEP] 1. Solr 프로세스"
SOLR_PROC=$(pgrep -f "solr\|start.jar" 2>/dev/null | wc -l || echo 0)
if [ "$SOLR_PROC" -gt 0 ]; then
    SOLR_PID=$(pgrep -f "solr" | head -1)
    echo " ${OK} Solr 실행 중 (PID: ${SOLR_PID})"
    RSS_MB=$(awk '/VmRSS/{print $2}' /proc/${SOLR_PID}/status 2>/dev/null | \
        awk '{printf "%d", $1/1024}' || echo "N/A")
    echo " RSS 메모리: ${RSS_MB} MB"
else
    echo " ${CRIT} Solr 프로세스 없음"
    RESULT=2
fi

# ── 2. 포트 리스닝 ────────────────────────────────────────
echo; echo "[$SEP] 2. 포트 리스닝"
ss -tlnp 2>/dev/null | grep -q ":${SOLR_PORT} " && \
    echo " ${OK} 포트 ${SOLR_PORT} LISTEN" || \
    { echo " ${CRIT} 포트 ${SOLR_PORT} LISTEN 없음"; RESULT=2; }

# ── 3. 시스템 정보 ────────────────────────────────────────
echo; echo "[$SEP] 3. Solr 시스템 정보"
if command -v curl &>/dev/null; then
    SYS=$(_solr "/solr/admin/info/system?wt=json")
    if [ -n "$SYS" ]; then
        SOLR_VER=$(echo "$SYS" | python3 -c \
            "import sys,json; d=json.load(sys.stdin); print(d.get('lucene',{}).get('solr-spec-version','?'))" 2>/dev/null)
        UPTIME=$(echo "$SYS" | python3 -c \
            "import sys,json; d=json.load(sys.stdin); ms=d.get('jvm',{}).get('jmx',{}).get('upTimeMS',0); \
            h=ms//3600000; m=(ms%3600000)//60000; print(f'{h}h {m}m')" 2>/dev/null || echo "N/A")
        echo " ${OK} Solr 버전: ${SOLR_VER}, 가동 시간: ${UPTIME}"
        # JVM 힙
        HEAP=$(echo "$SYS" | python3 -c \
            "import sys,json; d=json.load(sys.stdin); jvm=d.get('jvm',{}).get('memory',{}).get('raw',{}); \
            used=jvm.get('used',0)//1048576; max_=jvm.get('max',1)//1048576; \
            pct=used*100//max_ if max_>0 else 0; print(f'used={used}MB max={max_}MB ({pct}%)')" 2>/dev/null)
        echo " JVM 힙: ${HEAP}"
        if echo "$HEAP" | grep -oP '\d+(?=%)' | awk '{exit !($1>=85)}'; then
            echo " ${WARN} JVM 힙 사용률 85% 초과"
            [ $RESULT -lt 1 ] && RESULT=1
        fi
    else
        echo " ${CRIT} Solr 응답 없음"
        RESULT=2
    fi
fi

# ── 4. 코어/컬렉션 상태 ─────────────────────────────────
echo; echo "[$SEP] 4. 코어/컬렉션 상태"
if command -v curl &>/dev/null; then
    CORES=$(_solr "/solr/admin/cores?wt=json&indexInfo=false")
    if [ -n "$CORES" ]; then
        CORE_LIST=$(echo "$CORES" | python3 -c "
import sys, json
d = json.load(sys.stdin)
status = d.get('status', {})
for name, info in status.items():
    sz = info.get('index', {}).get('sizeInBytes', 0) // 1048576
    docs = info.get('index', {}).get('numDocs', 0)
    print(f'  {name:20s} docs={docs:>10,d} size={sz}MB')
" 2>/dev/null || echo "  파싱 실패")
        echo "$CORE_LIST"
        CORE_COUNT=$(echo "$CORES" | python3 -c \
            "import sys,json; d=json.load(sys.stdin); print(len(d.get('status',{})))" 2>/dev/null)
        echo " 총 코어 수: ${CORE_COUNT}"
    fi
fi

# ── 5. 쿼리 성능 통계 ────────────────────────────────────
echo; echo "[$SEP] 5. 쿼리 성능 통계"
if command -v curl &>/dev/null; then
    # 첫 번째 코어의 성능 지표
    FIRST_CORE=$(echo "$CORES" 2>/dev/null | python3 -c \
        "import sys,json; d=json.load(sys.stdin); print(list(d.get('status',{}).keys())[0])" 2>/dev/null || echo "")
    if [ -n "$FIRST_CORE" ]; then
        METRICS=$(_solr "/solr/${FIRST_CORE}/admin/mbeans?stats=true&cat=QUERYHANDLER&wt=json")
        AVG_TIME=$(echo "$METRICS" | python3 -c "
import sys, json
d = json.load(sys.stdin)
beans = d.get('solr-mbeans', [])
for i in range(0, len(beans), 2):
    if beans[i] == 'QUERYHANDLER':
        handlers = beans[i+1] if i+1 < len(beans) else {}
        for name, stats in handlers.items():
            if '/select' in name:
                qs = stats.get('stats', {})
                avg = qs.get('avgTimePerRequest', 0)
                rpc = qs.get('requests', 0)
                print(f'  /select: requests={rpc} avg={avg:.1f}ms')
" 2>/dev/null || echo "  쿼리 통계 없음")
        echo "$AVG_TIME"
    fi
fi

# ── 6. 로그 오류 ─────────────────────────────────────────
echo; echo "[$SEP] 6. 로그 오류"
for LOGDIR in "${SOLR_HOME}/server/logs" "${SOLR_HOME}/logs" "/var/log/solr"; do
    if [ -d "$LOGDIR" ]; then
        LOGFILE=$(ls -t "${LOGDIR}"/solr.log 2>/dev/null | head -1 || echo "")
        if [ -n "$LOGFILE" ] && [ -r "$LOGFILE" ]; then
            ERR=$(tail -1000 "$LOGFILE" | grep -cE "ERROR|WARN|Exception" || echo 0)
            echo " 최근 오류/경고: ${ERR}건 (${LOGFILE})"
            tail -1000 "$LOGFILE" | grep -E "ERROR|WARN" | tail -5 | sed 's/^/   /' || true
        fi
        break
    fi
done

# ── 요약 ─────────────────────────────────────────────────
echo
echo "======================================================"
case $RESULT in
    0) echo " 최종 결과: ${OK}   Solr 정상" ;;
    1) echo " 최종 결과: ${WARN} 주의 항목 있음" ;;
    2) echo " 최종 결과: ${CRIT} 즉시 조치 필요" ;;
esac
echo " 점검 완료: $(date '+%Y-%m-%d %H:%M:%S')"
echo "======================================================"
exit $RESULT
