#!/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) --hidetop    - не выводить строку для верхнего слоя overlay/aufs (changes)"
    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() {
    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
}

raw=""
reverse=""
hidetop=""
returnMe=""

while [[ $# -gt 0 ]]; do
    case "$1" in
        --raw)
            raw=yes
            if [[ -n "$2" && ! "$2" =~ ^- ]]; then
                returnMe="$2"
                shift
            fi
            ;;
        --reverse)
            reverse=yes
            ;;
        --hidetop)
            hidetop=yes
            ;;
        -h|--help)
            HLP
            ;;
        *)
            if [[ -d "$1" ]]; then
                ROOT="$1"
            elif [[ "$1" =~ ^[0-9]+$ ]]; then
                ROOT="$1"
            fi
            ;;
    esac
    shift
done

# Установка значения по умолчанию для returnMe
[[ "$raw" && -z "$returnMe" ]] && returnMe='$n $bundle $layer_perm $source $bundle_perm'

listing
