#!/bin/bash
# reparar-status-nulo-23702.sh [--aplicar]
#
# Repara los productos que quedaron con `maeplu.status` en NULL por el defecto
# del #23702, en TODAS las bases de produccion. Sin argumentos NO escribe nada:
# solo enseña que va a tocar. Con `--aplicar` respalda y escribe.
#
# Decidido por Manuel el 20-ago-2026, con el encuadre medido enfrente:
# TODAS las filas van a 0-Normal, incluidas las de sistema (`reparacion`,
# `NCDESCSI`, `NCDESCEXP`, `SALDOFAV`, `NCDESC`) y las DOS de la plantilla
# `mbinvinstalar` --esas ultimas con su autorizacion expresa, porque
# Programacion no la toca sin permiso--. Se le dijo el costo antes de decidir:
# esos productos de sistema EMPIEZAN a aparecer en el listado de 42 clientes,
# donde hoy no aparecen porque el listado es un INNER JOIN contra maestatus.
#
# Se corre DESDE app-4 (produccion), que es donde estan las credenciales:
#   ssh -A -p 4072 macrobase@132.226.40.48
#   bash reparar-status-nulo-23702.sh            # ensaya
#   bash reparar-status-nulo-23702.sh --aplicar  # respalda y escribe
#
# De noche y nunca un viernes, como manda la casa.
set -uo pipefail

APLICAR="${1:-ensayo}"
FECHA=$(TZ=America/Guatemala date +%Y-%m-%d-%H%M)
RESPALDO="/home/macrobase/respaldo-status-nulo-23702-$FECHA.tsv"
ESPERADAS=70   # medido el 20-ago-2026 15:00 hora de Guatemala (72 menos 2 copias)

CFG=/var/www/html/macrobase/mbinv/app/config/parameters.yml
CLAVE=$(grep -m1 "database_password" "$CFG" | sed -E "s/^[^:]*: *//" | tr -d "\"'")
MYSQL=(mysql -h prod.db.interno -u macrobase --connect-timeout=25)

consulta() { MYSQL_PWD="$CLAVE" "${MYSQL[@]}" -N -e "$1"; }

echo "== reparacion del #23702 =="
echo "   modo: $APLICAR    hora de Guatemala: $(TZ=America/Guatemala date '+%Y-%m-%d %H:%M')"

# --- 1. las bases afectadas, descubiertas, no de memoria -----------------------
# Se excluyen a proposito las COPIAS: `_temporales*` y las fechadas
# (`cliente_20260618_0939`). Son fotografias de un momento, y cambiarlas en
# silencio arruina cualquier comparacion contra el original -- justo lo que
# vienen a servir. El 20-ago-2026 eran 2 filas, en `_temporales3bien` y
# `_temporalespanpavailler`.
LISTA=$(consulta "
  SELECT GROUP_CONCAT(CONCAT('SELECT ', CHAR(39), table_schema, CHAR(39),
    ' base, plu, status FROM \`', table_schema, '\`.maeplu WHERE status IS NULL')
    SEPARATOR ' UNION ALL ')
  FROM information_schema.tables
  WHERE table_name='maeplu'
    AND table_schema NOT LIKE '\_temporales%'
    AND table_schema NOT REGEXP '_20[0-9]{6}'
    AND table_schema NOT LIKE '%copia%'
    AND table_schema NOT LIKE '%bak%';")
FILAS=$(MYSQL_PWD="$CLAVE" "${MYSQL[@]}" -N -e "SET SESSION group_concat_max_len=4000000; $LISTA" | awk 'NF' )
CUANTAS=$(printf '%s\n' "$FILAS" | grep -c . || true)

echo "   filas con status NULL ahora mismo: $CUANTAS (esperadas: $ESPERADAS)"
printf '%s\n' "$FILAS" | awk '{print $1}' | sort | uniq -c | sort -rn | sed 's/^/     /'

# --- 2. el freno de mano ------------------------------------------------------
# Si aparecieron muchas mas de las medidas, algo cambio desde el diagnostico y
# hay que volver a mirar antes de escribir. Menos no es problema: alguien pudo
# haberlas arreglado a mano.
if [ "$CUANTAS" -gt $((ESPERADAS + 10)) ]; then
    echo "!! ABORTA: hay $CUANTAS filas, muy por encima de las $ESPERADAS medidas."
    echo "   Revisar antes de escribir: puede haber otra causa activa."
    exit 1
fi
if [ "$CUANTAS" -eq 0 ]; then
    echo "   No hay nada que reparar."
    exit 0
fi

if [ "$APLICAR" != "--aplicar" ]; then
    echo
    echo "   ENSAYO: no se escribio nada. Para aplicar:"
    echo "     bash $0 --aplicar"
    exit 0
fi

# --- 3. respaldo fechado ANTES de escribir -----------------------------------
printf '%s\n' "$FILAS" > "$RESPALDO"
echo "   respaldo: $RESPALDO ($(grep -c . "$RESPALDO") filas)"
if [ "$(grep -c . "$RESPALDO")" -ne "$CUANTAS" ]; then
    echo "!! ABORTA: el respaldo no tiene las mismas filas que se van a tocar."
    exit 1
fi

# --- 4. el UPDATE, base por base --------------------------------------------
TOCADAS=0
for BASE in $(printf '%s\n' "$FILAS" | awk '{print $1}' | sort -u); do
    N=$(consulta "UPDATE \`$BASE\`.maeplu SET status = 0 WHERE status IS NULL;
                  SELECT ROW_COUNT();" 2>&1 | tail -1)
    # Si la base fallo, N no es un numero: se dice y se sigue. La verificacion
    # del final es la que manda -- no se da por bueno un UPDATE por no haber
    # visto un error.
    case "$N" in
        ''|*[!0-9]*) echo "     $BASE -> FALLO: $N" ;;
        *)           echo "     $BASE -> $N filas"; TOCADAS=$((TOCADAS + N)) ;;
    esac
done
echo "   total actualizado: $TOCADAS"

# --- 5. verificar el RESULTADO, no el comando --------------------------------
QUEDAN=$(MYSQL_PWD="$CLAVE" "${MYSQL[@]}" -N -e "SET SESSION group_concat_max_len=4000000; $LISTA" | awk 'NF' | grep -c . || true)
echo "   filas con status NULL despues: $QUEDAN"
if [ "$QUEDAN" -eq 0 ]; then
    echo "   OK: no queda ninguna."
else
    echo "!! Quedan $QUEDAN. Revisar."
    exit 1
fi

echo
echo "Para deshacerlo, con el respaldo:"
echo "  while IFS=\$'\\t' read -r B P S; do"
echo "    mysql -h prod.db.interno -u macrobase -e \"UPDATE \\\`\$B\\\`.maeplu SET status=NULL WHERE plu='\$P'\";"
echo "  done < $RESPALDO"
