#!/usr/bin/bash
# instalar-del-summa: instala (o desinstala) los archivos que un .summa dice
# que lleva el paquete, sin herramientas de Debian.
#
#     instalar-del-summa --destino DIR [opciones]
#
# El .summa es la fuente unica: la misma lista con la que summapack arma
# debian/install para el .deb se usa para instalar desde las fuentes, asi los
# dos caminos no se pueden desincronizar. Lo usan los "make install" de los
# paquetes que no son autotools (puyuspa, siru), que antes repetian este
# recorrido cada uno por su cuenta. Decision del autor, 08/10/2026: todos los
# paquetes dependen de summapack, que es lo que el instalador pone primero.
#
#   --summa ARCHIVO    el .summa; por omision el unico *.summa del directorio
#   --bloque NOMBRE    el bloque con la lista; por omision el primero que
#                      termine en _install (ARCHIVO_install,
#                      ARCHIVO_siru_install...)
#   --destino DIR      la raiz donde poner, ya con el DESTDIR y el prefijo
#                      adentro si hacen falta (obligatorio)
#   --quitar PREFIJO   lo que hay que sacarle al destino que trae el .summa,
#                      que es el del paquete: "usr/" o
#                      "var/www/simusol.org/public_html/"
#   --mapear V=N       cambia el destino V por N (repetible): siru pone sus
#                      modulos en lib/ y no en share/perl5, porque bin/siru
#                      los busca con use lib "$FindBin::Bin/../lib"
#   --origen DIR       de donde salen los archivos; por omision, el
#                      directorio del .summa
#   --desinstalar      los saca en lugar de ponerlos
#   --lista            solo dice que haria
#
# Permisos: 755 lo que esta bajo bin/ o termina en .pl, .sh o .py; 644 el
# resto. Es lo que hacen los paquetes en su override_dh_fixperms.
#
# Copyright (C) Diego Saravia <dsa@unsa.edu.ar>. GPL 3 o posterior.

set -u

summa=""; bloque=""; destino=""; quitar=""; origen=""
desinstalar=0; solo_lista=0
declare -a mapas=()

while [ $# -gt 0 ]; do
    case $1 in
        --summa)       summa=$2; shift ;;
        --bloque)      bloque=$2; shift ;;
        --destino)     destino=$2; shift ;;
        --quitar)      quitar=$2; shift ;;
        --mapear)      mapas+=("$2"); shift ;;
        --origen)      origen=$2; shift ;;
        --desinstalar) desinstalar=1 ;;
        --lista)       solo_lista=1 ;;
        -h|--ayuda|--help)
            sed -n '2,/^set -u/p' "$0" | sed -e 's/^# \?//' -e '$d'; exit 0 ;;
        *) echo "instalar-del-summa: no entiendo $1 (--ayuda)" >&2; exit 2 ;;
    esac
    shift
done

if [ -z "$summa" ]; then
    n=0
    for f in *.summa; do [ -f "$f" ] || continue; summa=$f; n=$((n+1)); done
    [ "$n" = 1 ] || { echo "instalar-del-summa: hay $n .summa aca; poner --summa" >&2; exit 2; }
fi
[ -f "$summa" ] || { echo "instalar-del-summa: no esta $summa" >&2; exit 2; }
[ -n "$destino" ] || { echo "instalar-del-summa: falta --destino (--ayuda)" >&2; exit 2; }
[ -n "$origen" ] || origen=$(dirname "$summa")

# el bloque: ARCHIVO_<algo>_install=$(cat << 'FIN_SUMMA' ... FIN_SUMMA
if [ -z "$bloque" ]; then
    bloque=$(grep -oE '^ARCHIVO_[A-Za-z0-9_]*install=' "$summa" | head -1 | sed 's/=$//')
    [ -n "$bloque" ] || { echo "instalar-del-summa: $summa no tiene ningun bloque *_install" >&2; exit 1; }
fi
lista=$(sed -n "/^$bloque=/,/^FIN_SUMMA/p" "$summa" | sed -e '1d' -e '$d' | grep -v '^[[:space:]]*$' || true)
[ -n "$lista" ] || { echo "instalar-del-summa: el bloque $bloque de $summa esta vacio" >&2; exit 1; }

# modo de un archivo: 755 si es programa
modo_de() {
    case $1 in
        bin/*|*/bin/*|*.pl|*.sh|*.py) echo 755 ;;
        *) echo 644 ;;
    esac
}

# el destino del .summa, con --quitar y los --mapear aplicados
destino_de() {
    local d=$1 m v n
    [ -n "$quitar" ] && d=${d#$quitar}
    for m in ${mapas[@]+"${mapas[@]}"}; do
        v=${m%%=*}; n=${m#*=}
        [ "$d" = "$v" ] && d=$n
    done
    printf '%s' "$d"
}

hubo=0
while read -r o d; do
    [ -n "${o:-}" ] || continue
    dest="$destino/$(destino_de "$d")"
    # el origen puede traer comodines (sistemas/*.json) o ser un directorio
    for f in $origen/$o; do
        if [ -d "$f" ]; then
            base=$(basename "$f")
            if [ "$solo_lista" = 1 ]; then
                echo "  $f/ (todo)  ->  $dest/$base/"
            elif [ "$desinstalar" = 1 ]; then
                rm -rf "$dest/$base"
            else
                mkdir -p "$dest/$base" || exit 1
                cp -r "$f/." "$dest/$base/" || exit 1
                find "$dest/$base" -type f -exec chmod 644 {} + 2>/dev/null || true
            fi
            hubo=1
            continue
        fi
        [ -e "$f" ] || { echo "instalar-del-summa: falta $f, que $summa pide" >&2; exit 1; }
        if [ "$solo_lista" = 1 ]; then
            echo "  $f  ->  $dest/$(basename "$f")"
        elif [ "$desinstalar" = 1 ]; then
            rm -f "$dest/$(basename "$f")"
        else
            install -d "$dest" || exit 1
            install -m "$(modo_de "$o")" "$f" "$dest" || exit 1
        fi
        hubo=1
    done
done <<< "$lista"

[ "$hubo" = 1 ] || { echo "instalar-del-summa: no se instalo nada de $bloque" >&2; exit 1; }

# al desinstalar, los directorios que quedaron vacios
if [ "$desinstalar" = 1 ]; then
    find "$destino" -depth -type d -empty -delete 2>/dev/null || true
fi
exit 0
