#!/usr/bin/env bash
# Instalador do ConectaSAMU Central (Ubuntu Core) — roda de um Ubuntu live.
#
# Uso (no live, com rede):
#   curl -fsSL https://public.tegrasw.com/conectasamu/install.sh | sudo bash
#
# O assistente: escolhe a imagem (mais recente via latest.txt ou nome
# manual), escolhe o disco de destino (excluindo o pendrive do live e
# discos montados), confirma com dupla checagem, baixa em STREAMING
# (download | sha256 | xz -d | dd — não precisa de espaço em disco no
# live) e verifica o checksum publicado ao final.
#
# ATENÇÃO: APAGA COMPLETAMENTE o disco escolhido.

set -euo pipefail

BASE_URL="${CONECTASAMU_BASE_URL:-https://public.tegrasw.com/conectasamu/images}"

erro() {
  echo "ERRO: $*" >&2
  exit 1
}

# curl ou wget, o que houver no live
baixar() {
  if command -v curl >/dev/null; then
    curl -fsSL "$1"
  else
    wget -qO- "$1"
  fi
}

# Todo o corpo vive em main(): com `curl | bash` o bash só executa depois
# de ler a função inteira do pipe — protege contra download parcial e
# permite religar o stdin ao terminal sem engolir o resto do script.
main() {

# Com `curl ... | sudo bash` o stdin é o PIPE do curl, não o teclado — o
# whiptail fica cego e as setas viram sequências de escape ecoadas no
# terminal. Religa o stdin ao /dev/tty.
if [ ! -t 0 ]; then
  [ -e /dev/tty ] || erro "sem terminal interativo (baixe o script e execute: sudo bash install.sh)."
  exec </dev/tty
fi

[ "$(id -u)" = "0" ] || erro "execute como root (sudo)."

command -v xz >/dev/null || erro "xz não encontrado no live."
command -v whiptail >/dev/null || erro "whiptail não encontrado no live."

# ---------------------------------------------------------------------------
# 1. Escolha da imagem
# ---------------------------------------------------------------------------

ULTIMA=$(baixar "$BASE_URL/latest.txt" 2>/dev/null | head -n1 | tr -d '[:space:]') || ULTIMA=""

if [ -n "$ULTIMA" ]; then
  ESCOLHA=$(whiptail --title "ConectaSAMU — Instalador" --menu \
    "Qual imagem instalar?" 15 70 2 \
    "recente" "Mais recente: $ULTIMA" \
    "manual" "Digitar o nome de outro arquivo" \
    3>&1 1>&2 2>&3) || exit 1
else
  ESCOLHA="manual"
fi

if [ "$ESCOLHA" = "recente" ]; then
  IMAGEM="$ULTIMA"
else
  IMAGEM=$(whiptail --title "ConectaSAMU — Instalador" --inputbox \
    "Nome do arquivo de imagem (ex.: conectasamu-central-20260729.img.xz).\nListagem: ${BASE_URL%/images}/" \
    12 70 3>&1 1>&2 2>&3) || exit 1
fi
[ -n "$IMAGEM" ] || erro "nenhuma imagem escolhida."
URL_IMAGEM="$BASE_URL/$IMAGEM"

# Checksum publicado (se existir, será verificado ao final)
SHA_PUBLICADO=$(baixar "$URL_IMAGEM.sha256" 2>/dev/null | awk '{print $1}') || SHA_PUBLICADO=""

# ---------------------------------------------------------------------------
# 2. Escolha do disco (excluindo o meio do live e discos montados)
# ---------------------------------------------------------------------------

# Disco que hospeda o live (não pode ser alvo)
DISCO_LIVE=""
for ponto in /cdrom /run/live/medium /media/cdrom; do
  fonte=$(findmnt -no SOURCE "$ponto" 2>/dev/null) || continue
  [ -n "$fonte" ] || continue
  pai=$(lsblk -no PKNAME "$fonte" 2>/dev/null | head -n1)
  DISCO_LIVE="${pai:-$(basename "$fonte")}"
  break
done

OPCOES=()
while IFS= read -r linha; do
  nome=$(awk '{print $1}' <<<"$linha")
  [ "$nome" = "$DISCO_LIVE" ] && continue
  # Disco com partição montada em / ou /boot não é alvo válido
  if lsblk -no MOUNTPOINTS "/dev/$nome" 2>/dev/null | grep -qE '^/$|^/boot'; then
    continue
  fi
  tamanho=$(awk '{print $2}' <<<"$linha")
  modelo=$(cut -d' ' -f3- <<<"$linha")
  OPCOES+=("$nome" "$tamanho  ${modelo:-—}")
done < <(lsblk -dno NAME,SIZE,MODEL --sort NAME | awk '$1 !~ /^(loop|sr|zram|ram)/')

[ ${#OPCOES[@]} -gt 0 ] || erro "nenhum disco de destino elegível encontrado."

DISCO=$(whiptail --title "ConectaSAMU — Instalador" --menu \
  "Disco de DESTINO (será APAGADO por completo):" 18 70 8 \
  "${OPCOES[@]}" 3>&1 1>&2 2>&3) || exit 1

# ---------------------------------------------------------------------------
# 3. Confirmação dupla
# ---------------------------------------------------------------------------

RESUMO="Imagem:  $IMAGEM\nDestino: /dev/$DISCO ($(lsblk -dno SIZE "/dev/$DISCO" | tr -d ' '))\n\nTODO o conteúdo de /dev/$DISCO será APAGADO."
whiptail --title "Confirmar instalação" --yesno "$RESUMO" 13 70 || exit 1

DIGITADO=$(whiptail --title "Última confirmação" --inputbox \
  "Para confirmar, digite o nome do disco ($DISCO):" 10 60 3>&1 1>&2 2>&3) || exit 1
[ "$DIGITADO" = "$DISCO" ] || erro "confirmação não confere — nada foi alterado."

# ---------------------------------------------------------------------------
# 4. Gravação (streaming: download | sha256 | xz | dd)
# ---------------------------------------------------------------------------

# Desmonta o que houver do disco alvo
while IFS= read -r mp; do
  [ -n "$mp" ] && umount -f "$mp" 2>/dev/null || true
done < <(lsblk -no MOUNTPOINTS "/dev/$DISCO" | grep -v '^$')
swapoff -a 2>/dev/null || true

echo
echo ">>> Baixando e gravando $IMAGEM em /dev/$DISCO ..."
echo ">>> (o progresso abaixo é da GRAVAÇÃO no disco)"
echo

HASH_ARQ=$(mktemp)
baixar "$URL_IMAGEM" |
  tee >(sha256sum | awk '{print $1}' > "$HASH_ARQ") |
  xz -dc |
  dd of="/dev/$DISCO" bs=4M conv=fsync oflag=direct status=progress

sync
blockdev --rereadpt "/dev/$DISCO" 2>/dev/null || true

# ---------------------------------------------------------------------------
# 5. Verificação do checksum (do .xz baixado, calculado durante o stream)
# ---------------------------------------------------------------------------

HASH_BAIXADO=$(cat "$HASH_ARQ"); rm -f "$HASH_ARQ"
if [ -n "$SHA_PUBLICADO" ]; then
  if [ "$HASH_BAIXADO" = "$SHA_PUBLICADO" ]; then
    VERIFICACAO="Checksum SHA-256 verificado com o publicado. ✔"
  else
    whiptail --title "FALHA DE VERIFICAÇÃO" --msgbox \
      "O checksum do download NÃO confere com o publicado.\n\nBaixado:   $HASH_BAIXADO\nPublicado: $SHA_PUBLICADO\n\nNÃO use este disco — repita a instalação." 14 76
    erro "checksum divergente."
  fi
else
  VERIFICACAO="(sem .sha256 publicado — verificação de integridade pulada)"
fi

# ---------------------------------------------------------------------------
# 6. Fim
# ---------------------------------------------------------------------------

if whiptail --title "Instalação concluída" --yesno \
  "Imagem gravada em /dev/$DISCO.\n$VERIFICACAO\n\nNo primeiro boot o Ubuntu Core faz a instalação automática (zero-touch)\ne reinicia sozinho; depois configure a rede com:\n  sudo conectasamu.network-setup\n\nRemova o pendrive do live e reinicie agora?" 16 74; then
  reboot
fi

}

main "$@"
