#!/usr/bin/env bash
# optimize_v2_no_reprocesa.sh
# Comprime videos MP4 y evita reprocesar archivos ya optimizados.
#
# Motivo del cambio:
# La versión anterior dependía principalmente de metadata interna del MP4:
#   -metadata procesado="true"
# y luego consultaba con ffprobe format_tags=procesado.
# En algunos MP4 esa metadata personalizada no se conserva o ffprobe no la expone igual.
# Esta versión usa además un marcador externo robusto:
#   video.mp4.procesado.ok
#
# Uso:
#   bash optimize_v2_no_reprocesa.sh
#   bash optimize_v2_no_reprocesa.sh --dir /var/www/html/uploads/videos/2026-06-03
#   bash optimize_v2_no_reprocesa.sh --today
#   bash optimize_v2_no_reprocesa.sh --yesterday
#   bash optimize_v2_no_reprocesa.sh --dry-run

LOCK_FILE="/tmp/optimize_videos.lock"

exec 200>"$LOCK_FILE"

flock -n 200 || {
    echo "$(date) Ya existe otra ejecución activa. Saliendo."
    exit 0
}

set -o pipefail

BASE_DIR="/var/www/html/uploads"
DIRECTORIO="$BASE_DIR"
DRY_RUN=0

TARGET_BITRATE="200k"
# Si un video no tiene audio y su bitrate es menor o igual a este valor,
# se considera ya comprimido y se marca para no reprocesarlo.
SKIP_BITRATE_BPS=250000

FECHA="$(date +%Y%m%d_%H%M%S)"
LOG_DIR="/var/log/optimize_videos"
LOCK_FILE="/tmp/optimize_videos.lock"

mkdir -p "$LOG_DIR" 2>/dev/null || LOG_DIR="/tmp"
LOG_FILE="$LOG_DIR/optimize_$FECHA.log"

log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" | tee -a "$LOG_FILE"
}

usage() {
    cat <<USAGE
Uso:
  bash $0 [opciones]

Opciones:
  --dir RUTA       Procesa una ruta específica.
  --today          Procesa /var/www/html/uploads/videos/YYYY-MM-DD del día actual.
  --yesterday      Procesa /var/www/html/uploads/videos/YYYY-MM-DD del día anterior.
  --dry-run        Simula, no comprime ni reemplaza archivos.
  --help           Muestra esta ayuda.

Ejemplos:
  bash $0 --today
  bash $0 --yesterday
  bash $0 --dir /var/www/html/uploads/videos/2026-06-03
USAGE
}

while [[ $# -gt 0 ]]; do
    case "$1" in
        --dir)
            shift
            if [[ -z "${1:-}" ]]; then
                echo "Error: falta ruta después de --dir"
                exit 1
            fi
            DIRECTORIO="$1"
            ;;
        --today)
            DIRECTORIO="$BASE_DIR/$(date +%F)"
            ;;
        --yesterday)
            DIRECTORIO="$BASE_DIR/$(date -d 'yesterday' +%F)"
            ;;
        --dry-run)
            DRY_RUN=1
            ;;
        --help|-h)
            usage
            exit 0
            ;;
        *)
            echo "Opción no reconocida: $1"
            usage
            exit 1
            ;;
    esac
    shift
done

# Evitar ejecuciones simultáneas.
exec 200>"$LOCK_FILE"
if ! flock -n 200; then
    echo "Ya existe otra ejecución activa. Saliendo."
    exit 0
fi

if ! command -v ffmpeg >/dev/null 2>&1; then
    log "ERROR: ffmpeg no está instalado o no está en PATH."
    exit 1
fi

if ! command -v ffprobe >/dev/null 2>&1; then
    log "ERROR: ffprobe no está instalado o no está en PATH."
    exit 1
fi

if [[ ! -d "$DIRECTORIO" ]]; then
    log "ERROR: El directorio $DIRECTORIO no existe."
    exit 1
fi

log "Iniciando compresión de videos."
log "Directorio: $DIRECTORIO"
log "Modo dry-run: $DRY_RUN"
log "Bitrate objetivo: $TARGET_BITRATE"
log "------------------------------------------------"

TOTAL=0
SALTADOS=0
PROCESADOS=0
ERRORES=0
MARCADOS=0

get_bitrate_bps() {
    local file="$1"
    local br=""

    br="$(ffprobe -v error -select_streams v:0 -show_entries stream=bit_rate -of default=noprint_wrappers=1:nokey=1 "$file" 2>/dev/null | head -n 1 | tr -d '\r')"

    if [[ -z "$br" || "$br" == "N/A" || ! "$br" =~ ^[0-9]+$ ]]; then
        br="$(ffprobe -v error -show_entries format=bit_rate -of default=noprint_wrappers=1:nokey=1 "$file" 2>/dev/null | head -n 1 | tr -d '\r')"
    fi

    if [[ -z "$br" || "$br" == "N/A" || ! "$br" =~ ^[0-9]+$ ]]; then
        echo "0"
    else
        echo "$br"
    fi
}

get_audio_count() {
    local file="$1"
    ffprobe -v error -select_streams a -show_entries stream=index -of csv=p=0 "$file" 2>/dev/null | wc -l | tr -d ' '
}

while IFS= read -r -d '' video; do
    TOTAL=$((TOTAL + 1))

    video="$(echo "$video" | tr -d '\r')"
    marker="${video}.procesado.ok"

    if [[ ! -f "$video" ]]; then
        log "[ERROR] No existe físicamente: $video"
        ERRORES=$((ERRORES + 1))
        continue
    fi

    if [[ "$video" == *.tmp.mp4 || "$video" == *.tmp.*.mp4 ]]; then
        log "[SKIP] Temporal ignorado: $video"
        SALTADOS=$((SALTADOS + 1))
        continue
    fi

    # 1) Control robusto por marcador externo.
    # Si el marcador es más nuevo que el video, ese archivo ya fue procesado.
    if [[ -f "$marker" && "$marker" -nt "$video" ]]; then
        log "[SKIP] Ya procesado por marcador: $video"
        SALTADOS=$((SALTADOS + 1))
        continue
    fi

    # 2) Control secundario por metadata, para compatibilidad con ejecuciones anteriores.
    if ffprobe -v error -show_entries format_tags=procesado -of default=noprint_wrappers=1:nokey=1 "$video" 2>/dev/null | grep -qi "true"; then
        log "[SKIP] Ya procesado por metadata: $video"
        if [[ "$DRY_RUN" -eq 0 ]]; then
            touch "$marker"
        fi
        SALTADOS=$((SALTADOS + 1))
        continue
    fi

    # 3) Control adicional: si ya quedó sin audio y con bitrate bajo, marcar y saltar.
    # Esto evita reprocesar videos ya comprimidos cuya metadata no fue conservada.
    bitrate_bps="$(get_bitrate_bps "$video")"
    audio_count="$(get_audio_count "$video")"

    if [[ "$bitrate_bps" =~ ^[0-9]+$ && "$bitrate_bps" -gt 0 && "$bitrate_bps" -le "$SKIP_BITRATE_BPS" && "$audio_count" -eq 0 ]]; then
        log "[SKIP] Parece ya comprimido: ${bitrate_bps} bps, audio=${audio_count}. Marcando: $video"
        if [[ "$DRY_RUN" -eq 0 ]]; then
            touch "$marker"
        fi
        SALTADOS=$((SALTADOS + 1))
        MARCADOS=$((MARCADOS + 1))
        continue
    fi

    log "[PROC] Procesando: $video"
    log "       Bitrate actual: ${bitrate_bps} bps | Audio streams: ${audio_count}"

    tmp_video="${video%.mp4}.tmp.$$.$RANDOM.mp4"

    if [[ "$DRY_RUN" -eq 1 ]]; then
        log "       DRY-RUN: no se ejecuta ffmpeg."
        continue
    fi

    ffmpeg -nostdin -v error -i "$video" \
        -c:v libx264 \
        -b:v "$TARGET_BITRATE" \
        -preset medium \
        -an \
        -metadata procesado="true" \
        -metadata comment="procesado=true" \
        -y "$tmp_video"

    if [[ $? -eq 0 && -s "$tmp_video" ]]; then
        mv -f "$tmp_video" "$video"
        touch "$marker"
        log "       [OK] Video comprimido, reemplazado y marcado."
        PROCESADOS=$((PROCESADOS + 1))
    else
        log "       [ERROR] Falló la compresión. Manteniendo original."
        rm -f "$tmp_video"
        ERRORES=$((ERRORES + 1))
    fi

    log "------------------------------------------------"

done < <(find "$DIRECTORIO" -type f -iname "*.mp4" ! -iname "*.tmp.mp4" ! -iname "*.tmp.*.mp4" -print0)

log "Proceso finalizado."
log "Total detectados: $TOTAL"
log "Procesados: $PROCESADOS"
log "Saltados: $SALTADOS"
log "Marcados como ya comprimidos: $MARCADOS"
log "Errores: $ERRORES"
log "Log: $LOG_FILE"
