#!/bin/bash

project=$1
host=$2
shift;
shift;
rest_args=$@

swat_ini_file='swat.ini'

project=${project:=`pwd`}

if [ \(  -n "${project}"  \) -a \( -d "${project}" \) ]; then
    :
else
    echo "usage: swat project HOST:port prover-options"
    exit 1
fi

project=`perl -MFile::Spec -e '$i=$ARGV[0]; s{\/$}[], chomp for $i; print File::Spec->rel2abs($i)' $project`
safe_project=project
cache_dir=~/.swat/.cache/$$

test -f $project/host && host=${host:=`cat $project/host`}

if [ -n "${host}"  ] ; then

    # host validation; it should not contain '../'
    if perl -e '$l=shift(); $l=~/\.\.\// or exit 1' "${host}"; then
        echo "bad host: ${host}"
        exit 1
    fi

    rm -rf $cache_dir
    mkdir -p $cache_dir
    session_file=$cache_dir/session.ini
    bash_hook_lock_file=$cache_dir/bash.hook.lock
else
    echo "usage: swat project HOST:port prove-options"
    exit 1
fi


# save environment settings to session file
echo > $session_file
rm -rf $bash_hook_lock_file

if [ -n "${curl_params}" ]; then
    echo "curl_params=$curl_params" >> $session_file
fi

if [ -n "${ignore_http_err}" ]; then
    echo "ignore_http_err=$ignore_http_err" >> $session_file
fi

if [ -n "${port}" ]; then
    echo "port=$port" >> $session_file
fi

if [ -n "${try_num}" ]; then
    echo "try_num=$try_num" >> $session_file
fi

if [ -n "${prove_options}" ]; then
    echo "prove_options=$prove_options" >> $session_file
fi

if [ -n "${debug}" ]; then
    echo "debug=$debug" >> $session_file
fi

if [ -n "${debug_bytes}" ]; then
    echo "debug_bytes=$debug_bytes" >> $session_file
fi

if [ -n "${curl_max_time}" ]; then
    echo "curl_max_time=$curl_max_time" >> $session_file
fi

if [ -n "${curl_connect_timeout}" ]; then
    echo "curl_connect_timeout=$curl_connect_timeout" >> $session_file
fi


if [ -n "${swat_module}" ]; then
    echo "swat_module=$swat_module" >> $session_file
fi


test_root_dir=$cache_dir/prove
rm -rf $test_root_dir
mkdir -p $test_root_dir

tt=1

find_cmd="find $project -type f -name get.txt -o -name post.txt -o -name put.txt -o -name delete.txt"

for f in `$find_cmd`; do
    resource_dir=`perl -MFile::Spec -e '$sp=$ARGV[0]; s{\w+\.txt$}[] for $sp; chomp $sp; print File::Spec->rel2abs($sp)' $f`;

    unset try_num
    unset debug_bytes
    unset debug
    unset curl_max_time
    unset curl_connect_timeout
    unset curl_params
    unset port
    unset swat_module
    unset ignore_http_err

    http_method=`perl -e '$p=$ARGV[0]; $p=~/(\w+)\.txt$/ and print uc($1)' $f`;

    test -f ~/$swat_ini_file && source ~/$swat_ini_file
    test -f $project/$swat_ini_file && source $project/$swat_ini_file
    test -f 'swat.my' && source 'swat.my'
    test -f $resource_dir/$swat_ini_file && source $resource_dir/$swat_ini_file

    source $session_file

    # set defaults
    try_num=${try_num:=2}
    debug=${debug:=0}
    debug_bytes=${debug_bytes:=500}
    curl_max_time=${curl_max_time:=20}
    curl_connect_timeout=${curl_connect_timeout:=20}
    swat_module=${swat_module:=0}
    ignore_http_err=${ignore_http_err:=0}

    resource=`perl -e '$sp=$ARGV[0]; $p=$ARGV[1]; s{^$sp}[], s{\w+\.txt}[], s{/$}[] for $p; chomp $p; $p = "/"  unless $p; print $p' $project $f`;
    mkdir -p "${test_root_dir}/${resource}";


    if [ -n "${port}" ]; then
        $host="$host:$port"
    fi

    # execute swat project bash hook
    if test -f $bash_hook_lock_file; then
        :
    else
        test -f $project/hook.bash && source $project/hook.bash
        touch $bash_hook_lock_file
    fi

    curl_cmd="curl -f -X $http_method"

    curl_cmd="${curl_cmd} -k --connect-timeout $curl_connect_timeout -m $curl_max_time -D - -L --stderr -"

    if [ -n "${curl_params}" ]; then
       curl_cmd="$curl_cmd ${curl_params}"
    fi

    if [ "$swat_module" -eq '0' ]; then
        tfile="${test_root_dir}/${resource}/00.${http_method}.t"
    else
        tfile="${test_root_dir}/${resource}/00.${http_method}.m"
    fi

    tt=$((tt+1))

    echo > $tfile
    echo "package main;"  >> $tfile
    echo >> $tfile

    echo 'BEGIN { push @INC, q{'$project'/lib}; }'  >> $tfile

    echo >> $tfile
    echo "use strict;"  >> $tfile
    echo >> $tfile


    if [ "$swat_module" -eq '0' ]; then
        echo "use Test::More q{no_plan};"  >> $tfile
    fi


    echo "use swat;"  >> $tfile

    echo >> $tfile
    echo >> $tfile

    echo "new_story();"  >> $tfile
    echo >> $tfile

    echo "set_prop( hostname => q{$host} );" >> $tfile
    echo "set_prop( resource => q{$resource} );" >> $tfile
    echo "set_prop( http_method => q{$http_method} );" >> $tfile
    echo "set_prop( curl_cmd => q{$curl_cmd} );" >> $tfile
    echo "set_prop( ignore_http_err => $ignore_http_err );" >> $tfile

    echo "set_prop( project => q{$project} );" >> $tfile
    echo "set_prop( test_root_dir => q{$test_root_dir} );" >> $tfile
    echo "set_prop( resource_dir => q{$resource_dir} );" >> $tfile


    echo "set_prop( debug => $debug );" >> $tfile
    echo "set_prop( debug_bytes => $debug_bytes );" >> $tfile
    echo "set_prop( try_num => $try_num );" >> $tfile

    echo "set_prop( swat_module => $swat_module );" >> $tfile
    echo "set_prop( check_list => q{$f} );" >> $tfile

    if [ "$swat_module" -eq '1' ]; then
        echo >> $tfile
        echo "apply_module_variables();"  >> $tfile
        echo >> $tfile
    fi

    echo >> $tfile
    echo >> $tfile

    test -f $resource_dir/hook.pm && echo "do_perl_file('${resource_dir}/hook.pm');"  >> $tfile

    echo >> $tfile

    echo "SKIP: {" >> $tfile
    echo -e "\t eval { generate_asserts(q{$f},1) }; die \$@ if \$@;" >> $tfile;
    echo >> $tfile
    echo "}" >> $tfile

    echo >> $tfile
    echo >> $tfile

    echo "end_of_story();"  >> $tfile
    echo >> $tfile
    echo >> $tfile
    echo '1;'>> $tfile
    echo >> $tfile

done;

test -f ~/$swat_ini_file && source ~/$swat_ini_file
test -f 'swat.my' && source 'swat.my'

source $session_file

export port

if [ -z "${rest_args}" ] && [ -n "${prove_options}" ]; then
    rest_args=("$prove_options")
    prove -m -r $rest_args  "$test_root_dir/$test_file";
elif [ -n "${rest_args}"  ]; then
    prove -m -r  $rest_args "$test_root_dir/$test_file";
else
    prove -m -r -v "$test_root_dir/$test_file";
fi






