#!/bin/bash
# /usr/local/bin/python-upload-watcher.sh
# Watcher para entregas de Programación ASIR1 via SFTP
# v7 — Nombre completo en notificaciones ([María Jara] en vez de [jara])
#
# - Batching por carpeta: UN mensaje XMPP con listado completo
# - Re-entregas: detecta delete+recreate (<120s)
# - Windows-safe: ignora Thumbs.db, desktop.ini, .DS_Store, *.tmp, __pycache__, *.pyc

WATCH_DIR="/home"

# --- Mapa usuario → nombre completo ---
fullname() {
    case "$1" in
        barja)     echo "Alex Barja" ;;
        barrios)   echo "Andrés Barrios" ;;
        cayo)      echo "Jared Cayo" ;;
        contrera)  echo "Luciano Contrera" ;;
        duque)     echo "Jorge Duque" ;;
        florea)    echo "Alejandro Florea" ;;
        gomes)     echo "Gabriel Gomes" ;;
        izquierdo) echo "Daniel Izquierdo" ;;
        jara)      echo "María Jara" ;;
        lillo)     echo "Fernando Lillo" ;;
        linares)   echo "Christopher Linares" ;;
        macedo)    echo "Eduardo Macedo" ;;
        martinez)  echo "Daniel Martínez" ;;
        munoz)     echo "Jordy Muñoz" ;;
        olcina)    echo "Jorge Olcina" ;;
        ponce)     echo "Francisco Ponce" ;;
        posada)    echo "Santiago Posada" ;;
        quiroz)    echo "Alexander Quiroz" ;;
        reynoso)   echo "Jorge Reynoso" ;;
        sierra)    echo "Leonel Sierra" ;;
        torrero)   echo "Mario Torrero" ;;
        *)         echo "$1" ;;  # fallback: username tal cual
    esac
}
LOG="/var/log/python-upload-watcher.log"
BATCH_DIR="/tmp/python-watcher-batches"
DELETE_DIR="/tmp/python-watcher-deletes"
QUIET_SECONDS=10

mkdir -p "$BATCH_DIR" "$DELETE_DIR"

log() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> "$LOG"
}

notify_xmpp() {
    /usr/local/bin/xmpp-notify.py "$1" >/dev/null 2>&1 &
}

is_junk() {
    case "${1,,}" in
        thumbs.db|desktop.ini|.ds_store|*.tmp|~\$*|~*.tmp) return 0 ;;
        __pycache__|*.pyc|*.pyo) return 0 ;;
        .git|.venv|.env|node_modules|.idea|.vscode) return 0 ;;
        *) return 1 ;;
    esac
}

# Filtrar paths que contengan directorios basura
is_junk_path() {
    case "$1" in
        */__pycache__/*|*/.git/*|*/.venv/*|*/node_modules/*|*/.idea/*|*/.vscode/*) return 0 ;;
        *) return 1 ;;
    esac
}

file_icon() {
    case "${1,,}" in
        *.py)   echo "🐍" ;;
        *.zip|*.rar|*.tar*|*.gz|*.bz2|*.7z) echo "📦" ;;
        *.md)   echo "📝" ;;
        *.txt)  echo "📄" ;;
        *.pdf)  echo "📕" ;;
        *.docx|*.doc) echo "📘" ;;
        *.png|*.jpg|*.jpeg|*.gif) echo "🖼️" ;;
        *)      echo "📎" ;;
    esac
}

batch_key() {
    echo "${1}_${2}" | tr '/ ' '__'
}

flush_batch() {
    local batchfile="$1"
    [[ ! -f "$batchfile" ]] && return

    local user dir tag file_count file_list label msg
    user=$(sed -n '1p' "$batchfile")
    dir=$(sed -n '2p' "$batchfile")
    tag=$(sed -n '3p' "$batchfile")
    file_count=$(tail -n +4 "$batchfile" | wc -l)

    [[ "$file_count" -eq 0 ]] && { rm -f "$batchfile"; return; }

    file_list=$(tail -n +4 "$batchfile")
    label="Entrega"
    [[ "$tag" == "re-entrega" ]] && label="♻️ Re-entrega"

    local display_name
    display_name=$(fullname "$user")
    msg="📁 [$display_name] $label ASIR1: $dir/ ($file_count ficheros)
$file_list"

    log "[$user] BATCH FLUSH ($tag): $dir/ → $file_count ficheros"
    notify_xmpp "$msg"
    rm -f "$batchfile"
}

flush_daemon() {
    while true; do
        sleep 3
        for batchfile in "$BATCH_DIR"/*.batch; do
            [[ ! -f "$batchfile" ]] && continue
            local last_mod now age
            last_mod=$(stat -c%Y "$batchfile" 2>/dev/null) || continue
            now=$(date +%s)
            age=$(( now - last_mod ))
            (( age >= QUIET_SECONDS )) && flush_batch "$batchfile"
        done
    done
}

flush_daemon &
FLUSH_PID=$!
trap "kill $FLUSH_PID 2>/dev/null" EXIT

log "=== Python Upload Watcher v7 iniciado ==="
notify_xmpp "🚀 [zzz] Python Upload Watcher v7 iniciado (ASIR1)"

# ---------------------------------------------------------
# Bucle principal — sin 'local', todo variables globales
# ---------------------------------------------------------
inotifywait -m -r \
    -e close_write -e moved_to -e create -e delete -e moved_from \
    --format "%e %w%f" "$WATCH_DIR" 2>/dev/null | \
while IFS= read -r line; do

    _event="${line%% /*}"
    _filepath="/${line#* /}"

    [[ ! "$_filepath" =~ ^/home/([^/]+)/python/(.+)$ ]] && continue

    _user="${BASH_REMATCH[1]}"
    _relpath="${BASH_REMATCH[2]}"
    _filename=$(basename "$_relpath")

    is_junk "$_filename" && continue
    is_junk_path "$_relpath" && continue

    # --- DELETE / MOVED_FROM ---
    if [[ "$_event" == *DELETE* || "$_event" == *MOVED_FROM* ]]; then
        if [[ "$_relpath" != */* ]]; then
            _bk=$(batch_key "$_user" "$_relpath")
            echo "$(date +%s)" > "$DELETE_DIR/$_bk"
            rm -f "$BATCH_DIR/${_bk}.batch"
            log "[$_user] BORRADA: $_relpath/"
        fi
        continue
    fi

    # --- CREATE directorio ---
    if [[ "$_event" == *CREATE* && -d "$_filepath" ]]; then
        # Solo carpetas de primer nivel bajo python/
        if [[ "$_relpath" != */* ]]; then
            _bk=$(batch_key "$_user" "$_relpath")
            _tag="new"

            if [[ -f "$DELETE_DIR/$_bk" ]]; then
                _del_ts=$(cat "$DELETE_DIR/$_bk")
                _now=$(date +%s)
                (( _now - _del_ts < 120 )) && _tag="re-entrega"
                rm -f "$DELETE_DIR/$_bk"
            fi

            printf '%s\n%s\n%s\n' "$(fullname "$_user")" "$_relpath" "$_tag" > "$BATCH_DIR/${_bk}.batch"
            log "[$_user] CARPETA ($_tag): $_relpath/ — batch abierto en $BATCH_DIR/${_bk}.batch"
        fi
        continue
    fi

    # --- CREATE fichero → skip (close_write viene después) ---
    [[ "$_event" == *CREATE* ]] && continue

    # --- close_write / moved_to → fichero completado ---
    _size=$(stat -c%s "$_filepath" 2>/dev/null || echo "?")
    _icon=$(file_icon "$_filename")

    if [[ "$_relpath" == */* ]]; then
        _topdir="${_relpath%%/*}"
        _bk=$(batch_key "$_user" "$_topdir")
        _batchfile="$BATCH_DIR/${_bk}.batch"

        if [[ -f "$_batchfile" ]]; then
            _subpath="${_relpath#*/}"
            echo "  $_icon $_subpath ($_size bytes)" >> "$_batchfile"
            log "[$_user] +BATCH: $_relpath ($_size bytes)"
            continue
        fi

        # Sin batch → individual
        log "[$_user] Subido: $_relpath ($_size bytes)"
        notify_xmpp "$_icon [$(fullname "$_user")] Entrega ASIR1: $_relpath ($_size bytes)"
    else
        log "[$_user] Subido: $_relpath ($_size bytes)"
        notify_xmpp "$_icon [$(fullname "$_user")] Entrega ASIR1: $_relpath ($_size bytes)"
    fi

done
