#!/bin/bash

# BigLinux GRUB Restore - System Detection Script
# www.biglinux.com.br
# Adaptado para GTK4 frontend
# License: GPL v2 or greater

# Translation setup
export TEXTDOMAINDIR="/usr/share/locale"
export TEXTDOMAIN=grub-restore

# Função para logar mensagens (agora com fallback para o console se o log falhar)
log_message() {
    local msg="$(date '+%Y-%m-%d %H:%M:%S'): $1"
    echo "$msg" >&2
}

# Função para desmontar partições com segurança
safe_unmount() {
    local partition="$1"
    if mountpoint -q "$partition" 2>/dev/null; then
        log_message "Unmounting $partition"
        umount -l "$partition" 2>/dev/null || true
    fi
}

# Garantir que o script rode como root
if [[ $EUID -ne 0 ]]; then
   log_message "Este script precisa ser executado como root."
   exit 1
fi

log_message "Starting system detection..."

# Limpeza inicial e criação de arquivos temporários com permissões corretas
rm -f /tmp/os-prober /tmp/efi-partitions /tmp/grub-disks
touch /tmp/os-prober /tmp/efi-partitions /tmp/grub-disks
chmod 666 /tmp/os-prober /tmp/efi-partitions /tmp/grub-disks

# 1. Desmontar partições para evitar conflitos com o os-prober
log_message "Unmounting existing partitions..."
# Adicionado suporte a mais tipos de FS e melhor filtro no blkid
for i in $(blkid -o device); do
    type=$(blkid -s TYPE -o value "$i")
    case "$type" in
        btrfs|ext[2-4]|xfs|vfat|ntfs)
            safe_unmount "$i"
            ;;
    esac
done

# 2. Executar os-prober para detectar sistemas Linux
log_message "Running os-prober to detect Linux systems..."
# O os-prober precisa que as partições não estejam montadas ou que ele mesmo as gerencie
GRUB_DISABLE_OS_PROBER=false os-prober | grep :linux | grep -v "timeshift" | grep -v 'subvol=@/' > /tmp/os-prober 2>/dev/null

# Pós-processamento para garantir que UUID e FSType estejam presentes
# O formato esperado pelo backend Python é: part:label:desc:type:fstype:uuid
# O os-prober padrão muitas vezes retorna apenas: part:label:desc:type
if [ -s /tmp/os-prober ]; then
    log_message "Post-processing os-prober results to add missing UUIDs..."
    temp_file=$(mktemp)
    while IFS= read -r line; do
        if [ -z "$line" ]; then continue; fi
        
        # Verifica se já tem UUID (simple check)
        if [[ "$line" != *"UUID="* ]]; then
            part=$(echo "$line" | cut -d: -f1)
            
            uuid=$(blkid -s UUID -o value "$part")
            fstype=$(blkid -s TYPE -o value "$part")
            
            # Remove trailing colons
            clean_line=$(echo "$line" | sed 's/:*$//')
            
            # Adiciona os campos faltantes. 
            # Assume-se que a linha original tem 4 campos. Se tiver menos, isso ajusta.
            # Formato alvo: part:label:desc:type:fstype:UUID=...
            
            # Conta campos atuais
            num_fields=$(echo "$clean_line" | awk -F: '{print NF}')
            
            # Reconstrói a linha para ter estrutura consistente
            # Se for 4 campos, adiciona fstype e uuid
            if [ "$num_fields" -le 4 ]; then
                new_line="${clean_line}:${fstype}:UUID=${uuid}"
                echo "$new_line" >> "$temp_file"
            else
                # Se já tiver mais campos mas sem UUID, tenta anexar
                new_line="${clean_line}:UUID=${uuid}"
                echo "$new_line" >> "$temp_file"
            fi
        else
            echo "$line" >> "$temp_file"
        fi
    done < /tmp/os-prober
    mv "$temp_file" /tmp/os-prober
    chmod 666 /tmp/os-prober
fi

# Adicionar partições Btrfs extras (importante para subvolumes específicos)
log_message "Checking for additional btrfs partitions..."
for i in $(blkid -t TYPE="btrfs" -o device); do
    if ! grep -q "$i" /tmp/os-prober 2>/dev/null; then
        label=$(blkid -s LABEL -o value "$i")
        if [ "$label" != "timeshift-btrfs" ]; then
            log_message "Adding btrfs partition: $i"
            [ -z "$label" ] && label="Btrfs_System"
            
            # Obter UUID para consistência
            uuid=$(blkid -s UUID -o value "$i")
            
            # Formato ajustado para compatibilidade com o parser Python
            # part:label:desc:type:fstype:UUID=uuid
            # Deixamos campos 3 e 4 vazios (desc e type do os-prober)
            echo "$i:$label:Linux::btrfs:UUID=$uuid" >> /tmp/os-prober 
        fi
    fi
done

# 3. Detecção de EFI
log_message "Starting EFI partition detection..."
mkdir -p /boot/efi

# Detecção melhorada do dispositivo de Live Boot (evita formatar o pendrive por erro)
DEVICE_LIVE_BOOT=$(lsblk -no pkname $(findmnt -n -o SOURCE /run/miso/bootmnt 2>/dev/null) 2>/dev/null)
log_message "Live boot device to exclude: $DEVICE_LIVE_BOOT"

# Escanear por partições EFI (Force Mode - All VFAT partitions)
# Using lsblk to be more robust and listing all VFAT/FAT32 without mounting checks
log_message "Scanning for potential EFI (vfat/fat) partitions..."
lsblk -ln -o PATH,FSTYPE | awk 'tolower($2) ~ /fat/ {print $1}' | while read -r i; do
    # Pula se for o dispositivo do Live Boot
    if [ -n "$DEVICE_LIVE_BOOT" ]; then
        [[ "$i" == *"$DEVICE_LIVE_BOOT"* ]] && continue
    fi
    
    log_message "Found potential EFI partition: $i"
    echo "$i" >> /tmp/efi-partitions
done

# 4. Detecção de Discos Físicos (Melhorado para NVMe e SSDs)
log_message "Starting disk detection..."
# lsblk -d (apenas dispositivos físicos) -n (sem cabeçalho)
for dev_raw in $(lsblk -dno NAME | grep -v "zram" | grep -v "loop" | grep -v "sr"); do
    # Normalize dev name (strip /dev/ prefix if present)
    dev=${dev_raw#/dev/}

    # Pula o disco do Live Boot (apenas se definido)
    if [ -n "$DEVICE_LIVE_BOOT" ]; then
        clean_live_boot=${DEVICE_LIVE_BOOT#/dev/}
        if [[ "$dev" == "$clean_live_boot" ]]; then
            log_message "Skipping live boot device (exact match): $dev"
            continue
        fi
    fi
    
    # Get details individually to avoid parsing issues
    size=$(lsblk -dn -o SIZE "/dev/$dev" | head -n1)
    if [ -z "$size" ]; then size="Unknown"; fi
    
    model=$(lsblk -dn -o MODEL "/dev/$dev" | head -n1)
    # Limpeza básica de strings
    clean_model=$(echo "${model:-Unknown_Disk}" | tr ' ' '_')
    
    pttype=$(lsblk -dn -o PTTYPE "/dev/$dev" | head -n1)
    clean_pttype=$(echo "${pttype:-unknown}" | tr ' ' '_')
    
    echo "/dev/${dev} ${size} ${clean_model} ${clean_pttype}" >> /tmp/grub-disks
    log_message "Added disk: /dev/${dev} (${size}, ${clean_model}, ${clean_pttype})"
done

log_message "Detection completed. Systems: $(wc -l < /tmp/os-prober), EFI: $(wc -l < /tmp/efi-partitions), Disks: $(wc -l < /tmp/grub-disks)"

exit 0
