#!/bin/sh
#vim:filetype=sh
#vim:shiftwidth=8

set -e
echo -n "$0: "

MOUNTPOINT=/mnt/unionfs
DEBUG=0

function create_hierarchy {
	chattr -R -i /n/lower
        rm -rf /n/lower/*

        while read LINE
        do
                if [ "$LINE" = "" ] ; then
                    continue
                fi
                TYPE=`echo $LINE | cut -d' ' -f 1`
                NAME=`echo $LINE | cut -d' ' -f 2`

		unset DIR FILE IMMUTABLE SOURCE	

		( echo $TYPE | grep -q d ) && DIR=1
		( echo $TYPE | grep -q f ) && FILE=1
		( echo $TYPE | grep -q i ) && IMMUTABLE=1
		( echo $TYPE | grep -q s ) && SOURCE=1

		if [ ! -z "$SOURCE" ] ; then
			if [ ! -z "$DIR" ] ; then
				echo "BAD TYPE (rename sources cannot be directories): $TYPE" 1>&2
				exit 1
			fi
			FILE=1
		fi

		if [ ! -z "$IMMUTABLE" ] ; then
			if [ -z "$DIR" ] ; then
				FILE=1
			fi
		fi

		if [ ! -z "$DIR" -a ! -z "$FILE" ] ; then
			echo "BAD TYPE (both a file and directory) : $TYPE" 1>&2
			exit 1
		fi


		if [ ! -z "$DIR" -a ! -z "$SOURCE" ] ; then
			echo "Directories can not be sources: $TYPE" 1>&2
			exit 1
		fi
		

                if [ ! -z "$DIR" ] ; then
                        mkdir -p $NAME
                elif [ ! -z "$FILE" ] ; then
                        mkdir -p `dirname $NAME` || exit $?
                        echo $NAME > $NAME || exit $?
			if [ ! -z "$SOURCE" ] ; then
                        	echo "Source file." > $NAME || exit $?
			else 
                        	echo $NAME > $NAME || exit $?
			fi
		else
			echo "What type am i: $TYPE" 1>&2
			exit $?
		fi
	
                if [ ! -z "$IMMUTABLE" ] ; then
			chattr +i $NAME || exit $?
		fi
        done
}

function check_hierarchy {
        ( find $1 -type d -printf 'd %p\n' ; find $1 -type f -printf 'f %p\n' ; find $1 -type b -printf 'b %p\n' ; find $1 -type c -printf 'c %p\n' ; find $1 -type l -printf 'l %p\n') | sort > /tmp/check-$$
        grep -v '^$' | sort | diff -u - /tmp/check-$$
        ERR=$?
        rm -f /tmp/check-$$
        return $ERR
}

function mount_union {
        if [ -z "$1" ] ; then
                OPTION="debug=$DEBUG,dirs="
        else
                OPTION="$1,debug=$DEBUG,dirs="
        fi

        shift

        while [ "$#" -gt 0 ]
        do
                OPTION="$OPTION$1" 
                if [ "$#" -ne "1" ] ; then
                        OPTION="$OPTION"":"
                fi
                shift
        done

        mount -t unionfs -o $OPTION none $MOUNTPOINT 

        return $?
}

function unmount_union {
    umount $MOUNTPOINT 
    return $?
}



function checkfile_after_remove {
    if [ -e "$1" ] ; then
        echo "$1 still exists after trying to unlink!"
        return 1
    fi
    return 0
}


function checkfile_after_create {
    if [ ! -e "$1" ] ; then
        echo "$1 does not exist after trying to create it!"
        return 1
    fi
    return 0
}

function checktype {
    F=$1
    CHECK=$2

    if [ "$CHECK" = "-" ] ; then
        [ ! -e "$F" ]
    elif [ "$CHECK" = "f" ] ; then
        [ -f "$F" ] 
    elif [ "$CHECK" = "d" ] ; then
        [ -d "$F" ]
    elif [ "$CHECK" = "b" ] ; then
        [ -b "$F" ]
    elif [ "$CHECK" = "c" ] ; then
        [ -c "$F" ]
    elif [ "$CHECK" = "l" ] ; then
        [ -l "$F" ]
    else
        echo "Unknown check '$CHECK'" 1>&2
        /bin/false
    fi
    ERR=$?

    if [ "$ERR" != "0" ] ; then
        echo "$F doesn't match '$CHECK'" 1>&2
        ls -ld $F 1>&2
    fi

    return $ERR
}

function shouldfail {
	if $* 2>/tmp/saveout-$$ ; then
		echo "UNWANTED SUCCESS: " $*
		cat /tmp/saveout-$$
		return 1
	fi
	rm -f /tmp/saveout-$$
	return 0
}
