#!/usr/bin/env bash
export GUILE_AUTO_COMPILE=0

if [ -z "$srcdir" ]; then
    echo >&2 "the \`srcdir' environment variable needs to be set to this script's location"
    exit 1
fi

source ${srcdir}/test-util

# run `scribbu m3u ...'
# usage: run_m3u var_to_rcv_stdout var_to_rcv_stderr var_to_rcv_status args...
# for instance:
#     run_m3u out err stat -o foo.m3u foo.mp3 bar.mp3
# will execute `scribbu -o foo.m3u foo.mp3 bar.mp3'; on return the process'
# stdout will be in `out', stderr in `err', and exit status in `stat'. Note
# that due to quoting issues, any `'' or ``' characters will have been
# replaced with `:'.
function run_m3u
{
    local __stdout=$1
    local __stderr=$2
    local __status=$3
    shift 3

    verbose `pwd`
    verbose ${m3u_scribbu_dir}/scribbu -L ${srcdir}/../scheme m3u $@
    # Cf. https://stackoverflow.com/questions/11027679/store-capture-stdout-and-stderr-in-different-variables-bash
    local t_std
    local t_err
    local t_stat
    # eval "$(${m3u_scribbu_dir}/scribbu -L ${srcdir}/../scheme m3u $@ \
    # 2> >(t_err=$(cat); typeset -p t_err) \
    #  > >(t_std=$(cat); typeset -p t_std) ); t_stat=$?"
    eval "$(${m3u_scribbu_dir}/scribbu -L ${srcdir}/../scheme m3u $@ \
    2> >(t_err=$(cat); declare -p t_err) \
     > >(t_std=$(cat); declare -p t_std) ); t_stat=$?"

    eval "$__stdout='$(echo $t_std|tr \' :|tr \" :)'"
    eval "$__stderr='$(echo $t_err|tr \' :|tr \" :)'"
    eval "$__status='$t_stat'"

    verbose $t_stat
    printf '=%.0s' $(seq 1 $m3u_cols) >&3
    verbose "$t_std"
    printf '=%.0s' $(seq 1 $m3u_cols) >&3
	echo "$t_err"
    printf '=%.0s' $(seq 1 $m3u_cols) >&3
}

###########################################################################
#                                   tests                                 #
###########################################################################

# "smoke tests"-- if these don't pass, something's very wrong
function smoke_tests()
{
    local out
    local err
    local stat

    # can we get a help message?
    run_m3u out err stat -h

    [ $stat -eq 0 ] || fail "smoke_tests: non-zero status for -h"
    [ -z "$err" ] || fail "smoke_tests: non-nil stderr for -h"
    [ -n "$out" ] || fail "smoke_tests: empty stdout for -h"

    here=`pwd`
    set_testdir ${srcdir} $m3u_testdir smoke_tests LAME_aots_3951.mp3 \
                VBRI_16M.mp3 sat.mp3 id3v2.3.tag

    run_m3u out err stat LAME_aots_3951.mp3
    [ $stat -eq 0 ] || fail "smoke_tests: non-zero status on LAME_aots_3951.mp3"
    [ -z "$err" ] || fail "smoke_tests: non-nil stderr for LAME_aots_3951.mp3"
    # Somehow, the \n gets translated to a space(?) Also, I need to use
    # `test', not `[' (??)
    test "${out}" = $'#EXTINF:5,LAME_aots_3951 LAME_aots_3951.mp3' ||
        fail "smoke_tests: got \"$out\" for LAME_aots_3951.mp3"

    run_m3u out err stat VBRI_16M.mp3
    [ $stat -eq 0 ] || fail "smoke_tests: non-zero status on VBRI_16M.mp3"
    [ -z "$err" ] || fail "smoke_tests: non-nil stderr for VBRI_16M.mp3"
    test "${out}" = $'#EXTINF:1,VBRI_16M VBRI_16M.mp3' ||
        fail "smoke_tests: got \"$out\" for VBRI_16M.mp3"
    
    run_m3u out err stat sat.mp3
    [ $stat -eq 0 ] || fail "smoke_tests: non-zero status on sat.mp3"
    [ -z "$err" ] || fail "smoke_tests: non-nil stderr for sat.mp3"
    test "${out}" = $'#EXTINF:323,sat sat.mp3' ||
        fail "smoke_tests: got \"$out\" for sat.mp3"
    
    run_m3u out err stat id3v2.3.tag
    [ $stat -eq 0 ] || fail "smoke_tests: non-zero status on id3v2.3.mp3"
    [ -z "$err" ] || fail "smoke_tests: non-nil stderr for id3v2.3.mp3"
    test "${out}" = "#EXTINF:0,The Pogues - Lorca:s Novena id3v2.3.tag" ||
        fail "smoke_tests: got \"$out\" for id3v2.3.mp3"
    
}

###########################################################################
# parse options; `make check' will pass none, so be sure no options means
# execute test suite normally
###########################################################################

m3u_builddir=../src
m3u_cols=$(tput cols)
m3u_debug=false
m3u_help=false
m3u_nargs=0
m3u_scribbu_dir=../src
m3u_testdir=./test-m3u-tmp
m3u_verbose=false
m3u_prev_option=
for m3u_option
do
    # If the previous option required an argument, assign it now.
    if test -n "$m3u_prev_option"; then
        eval $m3u_prev_option=\$m3u_option
        m3u_prev_option=
        m3u_nargs=$(($m3u_nargs+1))
        continue
    fi

    # Parse out the argument option in $m3u_option, if present.
    case $m3u_option in
        *=?*) m3u_optarg=$(expr "X$m3u_option" : '[^=]*=\(.*\)') ;;
        *=)   m3u_optarg= ;;
        *)    m3u_optarg=yes ;;
    esac

    # Options are handled here:
    case $m3u_option in
        -d | --de | --deb | --debu | --debug)
            m3u_debug=true;;
        -h | --he | --hel | --help)
            m3u_help=yes;;
        -v | --ve | --ver | --verb | --verbo | --verbose)
            m3u_verbose=true;;
        *)
            cat >&2 <<EOF
Unrecognized option \`$m3u_option'.
Try \`$0 --help' for more information.
EOF
            exit 2;;
    esac

done

if test "$m3u_help" == "true"; then
    cat <<EOF
\`$0' -- test the \`m3u' sub-command

TODO(sp1ff): write me!
EOF
fi

if test "$m3u_verbose" == "true"; then
    exec 3>&1
else
    exec 3> /dev/null
fi

if test "$m3u_debug" == "true"; then
    set -x
fi

# Both must be absolute in order for `make-distcheck' to work
m3u_scribbu_dir=`cd "$m3u_scribbu_dir"; pwd`
[ -d "$m3u_testdir" ] || mkdir -p "$m3u_testdir"
m3u_testdir=`cd "$m3u_testdir"; pwd`
smoke_tests
