#!/bin/bash
# bajar-paquetes: baja paquetes del servidor de descargas, comprobando su md5,
# y si se pide los instala. La contraparte de subir-paquetes. Reemplaza a
# download.sh e installsumma.sh, que bajaban sin comprobar el certificado y
# averiguando la IP del servidor con 8.8.8.8 (07/10/2026, ver BIN.md).
#
#   bajar-paquetes [opciones] NOMBRE...
#
#   NOMBRE        el paquete: calcula, libtabular2-0, summapack...
#   --formato F   deb, rpm, tgz, tar.gz o summa. Por omision, el del sistema:
#                 deb en Debian y Ubuntu, rpm en Fedora, Red Hat y SUSE, tgz
#                 en los demas
#   --inestable   la ultima subida (NOMBRE_UNSTABLE...); por omision, la
#                 estable (NOMBRE_last...)
#   --version V   una version dada (6.0-38)
#   --dir D       donde dejarlos (por omision ~/.cache/summapack)
#   --instalar    instalarlos: apt, dnf/zypper, o instalar-tgz para los .tgz
#   --prueba      mostrar que bajaria e instalaria, sin hacerlo
#
# Cada archivo se baja con su .md5, y queda con su nombre de verdad (el que
# dice el .md5: calcula_6.0-38_amd64.deb, no calcula_last_amd64.deb). Si ya
# esta en el directorio con el md5 correcto, no se vuelve a bajar.
#
# El servidor: BAJAR_URL en el entorno o en ~/.config/simusol/subir; por
# omision https://simusol.org/downloads. Admite file:// para probar.
#
# Es un solo archivo, sin mas que bash, curl y md5sum: installsumma lo baja
# del servidor para instalar summapack en una maquina que no lo tiene.
set -euo pipefail

[ -f "$HOME/.config/simusol/subir" ] && . "$HOME/.config/simusol/subir"
URL=${BAJAR_URL:-https://simusol.org/downloads}
DIR=${BAJAR_DIR:-$HOME/.cache/summapack}

formato=''; etiqueta=last; instalar=0; prueba=0; nombres=()
while [ $# -gt 0 ]; do
    case "$1" in
        --formato)   formato=$2; shift ;;
        --inestable) etiqueta=UNSTABLE ;;
        --version)   etiqueta=$2; shift ;;
        --dir)       DIR=$2; shift ;;
        --instalar)  instalar=1 ;;
        --prueba)    prueba=1 ;;
        -h|--help)   sed -n '2,29s/^# \{0,1\}//p' "$0"; exit 0 ;;
        -*)          echo "bajar-paquetes: no conozco $1 (--help)" >&2; exit 2 ;;
        *)           nombres+=("$1") ;;
    esac
    shift
done
set -- "${nombres[@]+"${nombres[@]}"}"
[ $# -gt 0 ] || { echo "uso: bajar-paquetes [opciones] NOMBRE... (--help)" >&2; exit 2; }

# el formato del sistema, como lo diria distro (sin depender de el)
sistema() {
    local id='' like=''
    if [ -r /etc/os-release ]; then
        id=$(. /etc/os-release; echo "${ID:-}")
        like=$(. /etc/os-release; echo "${ID_LIKE:-}")
    fi
    case " $id $like " in
        *" debian "*|*" ubuntu "*) echo deb ;;
        *" fedora "*|*" rhel "*|*" centos "*|*" suse "*|*" opensuse "*|*" mandriva "*) echo rpm ;;
        *) if command -v dpkg >/dev/null; then echo deb
           elif command -v rpm >/dev/null; then echo rpm
           else echo tgz; fi ;;
    esac
}
[ -n "$formato" ] || formato=$(sistema)
case "$formato" in deb|rpm|tgz|tar.gz|summa) ;; *) echo "bajar-paquetes: formato desconocido: $formato" >&2; exit 2 ;; esac

arq_deb=$(dpkg --print-architecture 2>/dev/null || { case "$(uname -m)" in x86_64) echo amd64 ;; aarch64) echo arm64 ;; *) uname -m ;; esac; })
arq_rpm=$(uname -m)

# los nombres que puede tener en el servidor
candidatos() {
    local n=$1 e=$etiqueta
    case "$formato" in
        deb)    echo "${n}_${e}_${arq_deb}.deb ${n}_${e}_all.deb" ;;
        tgz)    echo "${n}_${e}_${arq_deb}.tgz ${n}_${e}_all.tgz" ;;
        rpm)    echo "${n}-${e}.${arq_rpm}.rpm ${n}-${e}.noarch.rpm" ;;
        tar.gz) echo "${n}_${e}.tar.gz" ;;
        summa)  echo "${n}_${e}.summa" ;;
    esac
}

traer() {   # traer ARCHIVO_REMOTO DESTINO: falla en silencio si no esta
    curl -fsSL --retry 2 -o "$2" "$URL/$1" 2>/dev/null
}

mkdir -p "$DIR"
bajados=()
for nombre in "$@"; do
    hallado=''
    for c in $(candidatos "$nombre"); do
        if [ $prueba = 1 ]; then
            echo "  [prueba] probaria $URL/$c (y su .md5)"
            continue
        fi
        md5tmp=$(mktemp)
        if traer "$c.md5" "$md5tmp"; then
            suma=$(cut -d' ' -f1 < "$md5tmp")
            real=$(awk '{print $2}' < "$md5tmp" | sed 's/^\*//')
            [ -n "$real" ] || real=$c
            real=$(basename "$real")
            if [ -f "$DIR/$real" ] && [ "$(md5sum < "$DIR/$real" | cut -d' ' -f1)" = "$suma" ]; then
                echo "ya estaba: $DIR/$real"
            else
                traer "$c" "$DIR/$real.parcial" || { rm -f "$md5tmp"; echo "no se pudo bajar $URL/$c" >&2; exit 1; }
                if [ "$(md5sum < "$DIR/$real.parcial" | cut -d' ' -f1)" != "$suma" ]; then
                    rm -f "$DIR/$real.parcial" "$md5tmp"
                    echo "bajar-paquetes: $c bajo con otro md5 que el del servidor: se descarta" >&2
                    exit 1
                fi
                mv "$DIR/$real.parcial" "$DIR/$real"
                echo "bajado: $DIR/$real"
            fi
            cp "$md5tmp" "$DIR/$real.md5"
            rm -f "$md5tmp"
            hallado=$DIR/$real
            break
        fi
        rm -f "$md5tmp"
    done
    if [ $prueba = 0 ]; then
        [ -n "$hallado" ] || { echo "bajar-paquetes: no hay $nombre ($formato, $etiqueta) en $URL" >&2; exit 1; }
        bajados+=("$hallado")
    else
        bajados+=("$DIR/$(candidatos "$nombre" | cut -d' ' -f1)")
    fi
done

[ $instalar = 1 ] || exit 0

orden() {
    if [ $prueba = 1 ]; then echo "  [prueba] $*"; else echo "+ $*"; "$@"; fi
}
sudo_si_hace_falta() { if [ "$(id -u)" = 0 ]; then orden "$@"; else orden sudo "$@"; fi; }

case "$formato" in
    deb)
        rutas=(); for b in "${bajados[@]}"; do rutas+=("$(readlink -f "$b" 2>/dev/null || echo "$b")"); done
        sudo_si_hace_falta apt-get install --yes "${rutas[@]}" ;;
    rpm)
        if command -v dnf >/dev/null; then sudo_si_hace_falta dnf install -y "${bajados[@]}"
        elif command -v zypper >/dev/null; then sudo_si_hace_falta zypper install -y "${bajados[@]}"
        else sudo_si_hace_falta rpm -Uvh "${bajados[@]}"; fi ;;
    tgz)
        it=$(command -v instalar-tgz || echo "$(dirname "$0")/instalar-tgz")
        sudo_si_hace_falta "$it" "${bajados[@]}" ;;
    *)
        echo "bajar-paquetes: un $formato no se instala" >&2; exit 2 ;;
esac
