#!/bin/sh

ask=0

is_function() {
    type "$1" 2> /dev/null | sed "s/$1//" | grep -qwi function
}

curr_distro() {
    cat /etc/os-release | grep -G "^ID=" | sed 's/ID=//'
}

include() {
    [ -f "$1" ] || return 1
    . $1
    return 0
}

func() {
    if is_function $(echo "super_$2"); then
        sudo sh -c ". $1 && super_$2"
    fi
    is_function $2 && $2    
}

get_command() {
    case $1 in
        a*)
            printf "apply"
        ;;
        u*)
            printf "undo"
        ;;
        *) 
            echo "err: not supported" >&2
            exit 1
        ;;
    esac
}

# only run this *in crate dir*
run_crate() {
    include ./crate.sh || exit 1
    if [ -n "$describe" ]; then
        echo "desc($(basename $PWD)): $describe"
    fi
    cmd=$(get_command $1)
    scripts=${scripts:-"@self @distro"}
    for s in $scripts; do 
        echo "exec($(basename $PWD)): $s/$cmd"
        case $s in
            @self)
                func ./crate.sh $cmd
            ;;
            @distro)
                unset -f super_$cmd
                unset -f $cmd
                include ./crate.$(curr_distro).sh
                func ./crate.$(curr_distro).sh $cmd
                unset -f super_$cmd
                unset -f $cmd
                include ./crate.sh
            ;;
            *)
                sh $s
            ;;
        esac
    done
}

if [ $# -eq 2 ]; then
    [ -d crates/*$1 ] || exit 1
    cd crates/*$1
    run_crate $2
    cd ../..
else 
    [ $# -eq 0 ] && exit 2
    for crate in $(find ./crates -mindepth 1 -maxdepth 1 -type d | sort); do
        cd $crate
        run_crate $1
        cd ../..
    done
fi