#!/bin/bash
# mc-log-watcher.sh - Parse les logs MC en temps réel + historique récent

OUTPUT="/var/cache/mc-logs.json"
MAX_EVENTS=200
LOG_MC1="/srv/Minecraft/logs/latest.log"
LOG_MC2="/srv/Fabric/logs/latest.log"
TMP="$OUTPUT.tmp"
HISTORY_LINES=500  # Lignes historiques à lire au démarrage

declare -a EVENTS=()

touch "$OUTPUT"
chmod 644 "$OUTPUT"

write_json() {
    local json='{"events":['
    local first=true
    for event in "${EVENTS[@]}"; do
        $first || json+=','
        json+="$event"
        first=false
    done
    json+=']}'
    echo "$json" > "$TMP"
    mv "$TMP" "$OUTPUT"
}

add_event() {
    local server="$1"
    local type="$2"
    local message="$3"
    local ts="$4"  # optionnel: timestamp extrait du log

    # Si pas de timestamp fourni, utiliser l'heure actuelle
    if [ -z "$ts" ]; then
        ts=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
    fi

    message="${message//\\/\\\\}"
    message="${message//\"/\\\"}"

    local entry="{\"ts\":\"$ts\",\"server\":\"$server\",\"type\":\"$type\",\"msg\":\"$message\"}"
    EVENTS+=("$entry")

    if [ "${#EVENTS[@]}" -gt "$MAX_EVENTS" ]; then
        EVENTS=("${EVENTS[@]:1}")
    fi
}

# Extraire le timestamp ISO depuis une ligne de log MC
# Format: [HH:MM:SS] ...  → on utilise la date du jour + l'heure du log
extract_ts() {
    local line="$1"
    local hour
    if [[ "$line" =~ ^\[([0-9]{2}):([0-9]{2}):([0-9]{2})\] ]]; then
        hour="${BASH_REMATCH[1]}:${BASH_REMATCH[2]}:${BASH_REMATCH[3]}"
        echo "$(date -u +%Y-%m-%d)T${hour}Z"
    else
        date -u +"%Y-%m-%dT%H:%M:%SZ"
    fi
}

parse_line() {
    local server="$1"
    local line="$2"
    local write="$3"  # "write" pour écrire le JSON après

    [[ -z "$line" ]] && return

    local ts
    ts=$(extract_ts "$line")

    if [[ "$line" =~ ([A-Za-z0-9_]+)\ joined\ the\ game ]]; then
        add_event "$server" "join" "${BASH_REMATCH[1]} a rejoint le serveur" "$ts"
    elif [[ "$line" =~ ([A-Za-z0-9_]+)\ left\ the\ game ]]; then
        add_event "$server" "leave" "${BASH_REMATCH[1]} a quitté le serveur" "$ts"
    elif [[ "$line" =~ ([A-Za-z0-9_]+)\ (was\ slain|was\ shot|drowned|fell|burned|tried\ to\ swim|walked\ into|was\ killed|was\ blown|suffocated|hit\ the\ ground|starved|was\ poked|was\ impaled|was\ fireballed|was\ stung) ]]; then
        local msg="${line#*]: }"
        add_event "$server" "death" "$msg" "$ts"
    elif [[ "$line" =~ ([A-Za-z0-9_]+)\ has\ (made\ the\ advancement|completed\ the\ challenge|reached\ the\ goal)\ \[(.+)\] ]]; then
        add_event "$server" "advancement" "${BASH_REMATCH[1]} : ${BASH_REMATCH[3]}" "$ts"
    elif [[ "$line" =~ \[Server\ thread/INFO\]:\ \<([A-Za-z0-9_]+)\>\ (.+) ]]; then
        add_event "$server" "chat" "<${BASH_REMATCH[1]}> ${BASH_REMATCH[2]}" "$ts"
    elif [[ "$line" =~ Done\ \([0-9.]+s\)\!\ For\ help ]]; then
        add_event "$server" "start" "Serveur démarré" "$ts"
    elif [[ "$line" =~ Stopping\ the\ server ]]; then
        add_event "$server" "stop" "Serveur arrêté" "$ts"
    fi

    [ "$write" = "write" ] && write_json
}

# ===== Lire l'historique récent des deux logs =====
echo "[mc-log-watcher] Lecture historique ($HISTORY_LINES lignes)..."

if [ -f "$LOG_MC1" ]; then
    while IFS= read -r line; do
        parse_line "MC1" "$line"
    done < <(tail -n "$HISTORY_LINES" "$LOG_MC1")
fi

if [ -f "$LOG_MC2" ]; then
    while IFS= read -r line; do
        parse_line "MC2" "$line"
    done < <(tail -n "$HISTORY_LINES" "$LOG_MC2")
fi

write_json
echo "[mc-log-watcher] Historique chargé (${#EVENTS[@]} events). Surveillance en cours..."

# ===== Surveiller en temps réel =====
FIFO=$(mktemp -u /tmp/mc-watcher-XXXXXX)
mkfifo "$FIFO"
trap "rm -f $FIFO; kill 0" EXIT INT TERM

tail -F "$LOG_MC1" 2>/dev/null | sed 's/^/MC1|/' > "$FIFO" &
tail -F "$LOG_MC2" 2>/dev/null | sed 's/^/MC2|/' > "$FIFO" &

while IFS= read -r rawline; do
    server="${rawline%%|*}"
    line="${rawline#*|}"
    parse_line "$server" "$line" "write"
done < "$FIFO"
