#!/bin/bash
# barium helper scripts
# author: rosalinux.ru: betcher_
ROOT=/
if [ -f $(dirname $0)/lib ] ;  then
	. $(dirname $0)/lib
else
	. $(which lib) || exit 1
fi

HLP () {
	echo -e "$(basename $0) утилита для контроля слоев overlayfs/aufs"
	echo "Использование:"
	echo "	$(basename $0)			- список слоев основной rootfs OS barium"
	echo "	$(basename $0) 2 			- список слоев  созданной lib make_ovl/make_aufs с индексом 2"
	echo "	$(basename $0) --raw		- список в формате удобном для парсинга"
	echo "	$(basename $0) --raw  '"'$n $source'"'	- только нужные значения"
	echo "Доступные значения:"
	echo '  $n - layer number'
	echo '  $source - source of layer (module,image,dir,etc)'
	echo '  $bname_source - source base name'
	echo '  $dname_source - source dir name'
	echo '  $bundle - source mount point'
	echo '  $bname_bundle - bundle base name'
	echo '  $dname_bundle - bundle dir name'
	exit 1
}

# Ускоренный addZeros (без вызова wc и seq)
addZeros() {
    local num=$1
    local len=${#num}
    if (( len < 3 )); then
        printf "%0$((3 - len))d" "$num"
    else
        echo -n "$num"
    fi
}

header() {
    printf "%3s %-65s %s\n%-68s %s\n\n" \
        "N" "Bundle Mount point" "Layer perms" \
        "   Source" "Bundle perms"
}

listing() {
    local layer_perm=rw
    local n=0
    local bundle loop source bundle_perm
    local -a bundles

    if [[ "$hidetop" ]]; then
        bundles=( $(ls_union "$ROOT" hidetop) )
    else
        bundles=( $(ls_union "$ROOT") )
    fi

    [[ "$reverse" ]] && bundles=( $(printf '%s\n' "${bundles[@]}" | tac) )

    # Кешируем losetup -l для raw режима
    local loop_info
    [[ "$raw" ]] && loop_info=$(losetup -l)

    for bundle in "${bundles[@]}"; do
        bundle_perm=$([[ -w "$bundle" ]] && echo rw || echo ro)

        if [[ "$raw" ]]; then
         
            loop=$(findmnt -n -o SOURCE --target "$bundle" | tail -n1 | tr -d '],[')
            [[ "$loop" ]] || loop=$(df -P "$bundle" | awk 'END{print $1}')

            if [[ "$loop" ]]; then
                source=$(awk -v loop="$loop" '$1 == loop {print $6}' <<< "$loop_info")
                [[ "$source" ]] || source="$loop"
            else
                source="$loop"
            fi

            local dname_source=${source%/*} bname_source=${source##*/}
            local dname_bundle=${bundle%/*} bname_bundle=${bundle##*/}
            
            eval echo "$returnMe"
        else
            loop=$(findmnt -n -o SOURCE --target "$bundle" | tail -n1 | tr -d '],[')
            [[ "$loop" ]] || loop=$(df -P "$bundle" | awk 'END{print $1}')

            if [[ "$loop" ]]; then
                source=$(losetup -l | awk -v loop="$loop" '$1 == loop {print $6}')
                [[ "$source" ]] || source="$loop"
            else
                source="$loop"
            fi

            printf %3s "$(addZeros $n) ";
            printf %-65s "$bundle " ; printf %b "${color_default}"
            [ "$layer_perm" = "rw" ] && printf %b "${color_green}" ;
            printf "$layer_perm\n" ; printf %b "${color_default}"

            [ "$source" = "tmpfs" ] && printf %b "${color_blue}" ;
            echo "$source" |grep -q "^/dev/.*$"  && printf %b "${color_yellow}" ;

            printf %-68s "   $source " ;  printf %b "${color_default}"
            [ "$bundle_perm" = "rw" ] && printf %b "${color_green}" ;
            printf  "$bundle_perm\n" ; printf %b "${color_default}"
            echo ''
        fi
        ((n++))
        layer_perm=""
    done
}

for arg in "$@"; do
    case "$arg" in
        --raw) raw=yes
               shift
               returnMe="$1";;
        --reverse) reverse=yes;;
        --hidetop) hidetop=yes;;
        -h|--help) HLP;;
        *)
            if [[ -d "$arg" ]]; then
                ROOT="$arg"
            elif [[ "$arg" =~ ^[0-9]+$ ]]; then
                ROOT="$arg"
            fi
            ;;
    esac
done

[[ "$raw" && -z "$returnMe" ]] && returnMe='$n $bundle $layer_perm $source $bundle_perm'

listing
