## library functions

function die () {
    echo "!!! $@" >&2

    exit 1
}

# Execute command verbosely, and exit on failure
function cmd () {
    echo ">>> $@"

    [ $_MOCK ] && return 0

    eval "$@" # return $?
}

function expand_MB () {
    local size=${1^}

    case ${size: -1} in 
        G)
            size=$(( ${size%G} * 1024))

            ;;
    esac

    echo $size
}

function extract_iso () {
    iso=$1
    dst=$2

    [ ! -r "$iso" ] && die "Given .iso is not readable: $iso"
    [ -z "$dst" ] && die "Must give destination: $dst"
    [ -e "$dst" ] && die "Given destination already exists: $dst"

    # temporary mount
    mnt=$(mktemp -d mnt.XXXX)

    # clean on exit
    function cleanup () {
        if mountpoint -q $mnt; then
           sudo umount $mnt
        fi

        [ -d $mnt ] && rmdir $mnt

        return $1
    }

    # loop-mount
    cmd sudo mount -o loop $iso $mnt || cleanup 1

    # copy
    cmd cp -r $mnt $dst || cleanup 1

    # done, cleanup
    cleanup 0
}

function my_md5sum () {
    /usr/bin/md5sum $1 | (
        read md5sum path
        echo $md5sum
    )
}

function expand_template () {
    local tpl=$1
    local out=$2

    local linecount=0

    # read in each line at a time
    while IFS='' read -r line; do
        linecount=$((linecount + 1))

        if [ "${line:0:1}" == "#" ]; then
            # ignore comments; pass through as-is
            echo "$line"
        
        else
            # evaluate {...} expressions
            # a slight hack, but it works \o/
            # http://stackoverflow.com/questions/415677/how-to-replace-placeholders-in-a-text-file/7633579#7633579
            line="${line//\\/\\\\}"
            line="${line//\"/\\\"}"
            line="${line//\`/\\\`}"
            line="${line//\$/\\\$}"
            line="${line//{/\${}"   # This is just for vim: } "

            # echo "($line)" >&2
            (eval "echo \"$line\"") || die "Error at $tpl:$linecount: $line"
        fi
 
    done < $tpl > $out
}

# Recursive expand_template files from src -> dst
# XXX: not used
function expand_tree () {
    local src=$1
    local dst=$2
    local filter=${3:-'*'}

    for path in ${src}/${filter}; do
        local name=$(basename $path)
        local target=$dst/$name

        if [ -d $path ]; then
            echo "expand_tree: $path -> $target"
            echo "expand_tree $path $target $filter"

        elif [ -f $path ]; then
            echo "expand_file: $path -> $target"
            echo "expand_file $path $target"

        else
            echo "XXX: ignore weird file: $path"

        fi
    done
}
