#!/bin/bash
# mgfs.sh - Liste tous les disques physiques avec appartenance mergerfs, zfs ou unused
# Ajout d'un système de filtre (--usage, --serial, --model, --device)

ALL=$(mktemp)
MFS=$(mktemp)
ZFS=$(mktemp)

cleanup() {
    rm -f "$ALL" "$MFS" "$ZFS"
}
trap cleanup EXIT

#####################################
# 1. Lister tous les disques physiques
#####################################
list_all_disks() {
    lsblk -dn -o NAME,MODEL,SERIAL,SIZE | grep -E '^(sd|nvme)' | \
    awk '{
        dev=$1; size=$NF; serial=$(NF-1);
        model="";
        for(i=2;i<=NF-2;i++) model=model" "$i;
        gsub(/^ +| +$/,"",model);
        print "/dev/"dev"|"model"|"serial"|"size
    }' | sort -t'|' -k1 > "$ALL"
}

#####################################
# 2. Lister les disques mergerfs
#####################################
list_mergerfs_members() {
    UNIT=/etc/systemd/system/mnt-union.mount
    > "$MFS"

    if [[ -f "$UNIT" ]]; then
        sources=$(grep "^What=" "$UNIT" | cut -d= -f2 | tr ':' ' ')
        for src in $sources; do
            wwn=$(basename "$src")
            dev=$(ls -l /dev/disk/by-id/ | grep "$wwn" | grep -v part | awk '{print $11}' | sed 's|\.\./\.\./||')
            if [[ -n "$dev" ]]; then
                echo -e "/dev/$dev\tmergerfs:mnt-union" >> "$MFS"
            fi
        done
    fi
}

#####################################
# 3. Lister les disques ZFS
#####################################
list_zfs_members() {
    > "$ZFS"
    for pool in $(zpool list -H -o name 2>/dev/null || true); do
        zpool list -v "$pool" | awk 'NR>1 {print $1}' | while read -r dev; do
            [[ "$dev" =~ ^mirror|^raidz|^logs|^cache|^spares|^special ]] && continue
            [[ "$dev" == "$pool" ]] && continue

            if [[ -e "/dev/disk/by-id/$dev" ]]; then
                real_dev=$(readlink -f "/dev/disk/by-id/$dev")
            else
                real_dev="$dev"
            fi
            parent=$(lsblk -dn -no PKNAME "$real_dev" 2>/dev/null)
            [[ -n "$parent" ]] && disk="/dev/$parent" || disk="$real_dev"
            echo -e "$disk\tzfs:$pool"
        done
    done >> "$ZFS"
}

#####################################
# 4. Fusion et filtrage
#####################################
merge_and_display() {
    echo "DEVICE|MODEL|SERIAL|SIZE|USAGE"

    while IFS="|" read -r dev model serial size; do
        usage="unused"
        [[ -z "$serial" ]] && serial="-"
        [[ -z "$model" ]] && model="-"

        m_usage=$(grep -P "^$dev\s" "$MFS" | awk '{print $2}' | head -n1)
        z_usage=$(grep -P "^$dev\s" "$ZFS" | awk '{print $2}' | head -n1)

        if [[ -n "$m_usage" ]]; then
            usage="$m_usage"
        elif [[ -n "$z_usage" ]]; then
            usage="$z_usage"
        fi

        echo "$dev|$model|$serial|$size|$usage"
    done < "$ALL" | apply_filters | sort -t'|' -k5,5 -k1,1 | column -s '|' -t
}

#####################################
# 5. Appliquer les filtres
#####################################
apply_filters() {
    results=$(cat)

    [[ -n "$FILTER_USAGE" ]] && results=$(echo "$results" | grep -i "$FILTER_USAGE")
    [[ -n "$FILTER_SERIAL" ]] && results=$(echo "$results" | grep -i "$FILTER_SERIAL")
    [[ -n "$FILTER_MODEL" ]] && results=$(echo "$results" | grep -i "$FILTER_MODEL")
    [[ -n "$FILTER_DEVICE" ]] && results=$(echo "$results" | grep -i "$FILTER_DEVICE")

    echo "$results"
}

#####################################
# 6. Parser arguments
#####################################
show_help() {
    cat <<EOF
Usage: $0 [OPTIONS]

Liste les disques physiques avec appartenance mergerfs, zfs ou unused.

Options de filtrage :
  --usage <mergerfs|zfs|unused>   Filtrer selon l'appartenance
  --serial <substring>            Filtrer par numéro de série
  --model <substring>             Filtrer par modèle
  --device <substring>            Filtrer par nom du device (/dev/sdX, nvme...)

Autres :
  -h, --help                      Affiche cette aide

Exemples :
  $0 --usage mergerfs             Liste uniquement les disques mergerfs
  $0 --usage zfs                  Liste uniquement les disques ZFS
  $0 --model TOSHIBA              Filtre les disques dont le modèle contient "TOSHIBA"
  $0 --serial ZR5F8               Filtre les disques dont le numéro de série contient "ZR5F8"
  $0 --device /dev/sda            Filtre uniquement /dev/sda
EOF
}

while [[ $# -gt 0 ]]; do
    case "$1" in
        --usage)   FILTER_USAGE="$2"; shift 2 ;;
        --serial)  FILTER_SERIAL="$2"; shift 2 ;;
        --model)   FILTER_MODEL="$2"; shift 2 ;;
        --device)  FILTER_DEVICE="$2"; shift 2 ;;
        -h|--help) show_help; exit 0 ;;
        *) shift ;;
    esac
done

#####################################
# Exécution
#####################################
list_all_disks
list_mergerfs_members
list_zfs_members
merge_and_display