#!/bin/bash

################################################################################
################################################################################
########## This is the main-sqlite script for the automated xmpptest ###########
################################################################################
################################################################################

# create timestamp for working directory
TSTAMP=`date +"%y%m%d%H%M%S"`

echo zeit: $TSTAMP

# set directory path
CONFIG_DIR=/etc/jabberd
WORKING_DIR=$2/sqlite/$TSTAMP
PARENT_DIR=/tmp/xmpptest
DATABASE_DIR=$WORKING_DIR/db
DB_C2S=xmpptest_c2s.db
DB_SM=xmpptest_sm.db
LOG_DIR=$WORKING_DIR/log
PID_DIR=$WORKING_DIR/pid

# get FQDN (Fully Qualified Domain Name)
MACHINEHOST=`hostname -f`

# function to check if a value is present in an array
# usage: contains <array> <value>
contains () {
        array="$1[@]"
        seeking=$2
        in=1
        for elem in "${!array}";
        do
                if [[ $elem == $seeking ]]; then
                        in=0
                        break
                fi
        done
        return $in
}

# create random port numbers between [49152; 65535] until all are free
echo -e "create port numbers...\n"

PORTS_LIST=() # Array of free ports
while true
do
        # none is already in the list => create all at random
        if [ ${#PORTS_LIST[@]} -eq 0 ]; then
                ROUTER_PORT=$[ $[RANDOM % 16384] + 49152 ]      # default: 5347
                C2S_PORT=$[ $[RANDOM % 16384] + 49152 ]         # default: 5222
                S2S_PORT=$[ $[RANDOM % 16384] + 49152 ]         # default: 5269
        fi
        # one is already in the list => create two at random
        if [ ${#PORTS_LIST[@]} -eq 1 ]; then
                ROUTER_PORT=${PORTS_LIST[0]}
                C2S_PORT=$[ $[RANDOM % 16384] + 49152 ]
                S2S_PORT=$[ $[RANDOM % 16384] + 49152 ]
        fi
        # two are already in the list => create one at random
        if [ ${#PORTS_LIST[@]} = 2 ]; then
                ROUTER_PORT=${PORTS_LIST[0]}
                C2S_PORT=${PORTS_LIST[1]}
                S2S_PORT=$[ $[RANDOM % 16384] + 49152 ]
        fi

        PORTS=($ROUTER_PORT $C2S_PORT $S2S_PORT) # array with all created ports

        # test if port numbers are unique and free
        for k in ${PORTS[@]}
        do
		if ! (netstat -nl | grep -q $k || [ "$(contains PORTS_LIST $k)" ] ); then # port is unique and free
                        PORTS_LIST+=($k)
                fi
        done
	# if all ports are unique and free, exit the loop
        if [ ${#PORTS_LIST[@]} -eq 3 ]; then
		break
        fi
done

# create directories
echo -e "create directories...\n"

mkdir -p -m 777 $WORKING_DIR
mkdir -p -m 777 $DATABASE_DIR
mkdir -p -m 777 $LOG_DIR
mkdir -p -m 777 $PID_DIR

# edit xml-files with xmlstarlet command line tool
xml ed -u "c2s/local/id[@register-enable='mu']" -v $MACHINEHOST < $CONFIG_DIR/c2s.xml.dist > $WORKING_DIR/c2s.xml

xml ed -L -s "c2s/local/id[@register-enable='mu']" -t attr -n "password-change" -v "mu" $WORKING_DIR/c2s.xml

xml ed -L -u "c2s/authreg/module" -v sqlite $WORKING_DIR/c2s.xml

xml ed -L -u "c2s/io/max_fds" -v 80021 $WORKING_DIR/c2s.xml      # change max fd number

xml ed -L -u "c2s/authreg/sqlite/dbname" -v $DATABASE_DIR/$DB_C2S $WORKING_DIR/c2s.xml # db name for c2s

xml ed -u "sm/local/id" -v $MACHINEHOST < $CONFIG_DIR/sm.xml.dist > $WORKING_DIR/sm.xml

xml ed -L -u "sm/storage/driver" -v sqlite $WORKING_DIR/sm.xml

xml ed -L -u "sm/storage/sqlite/dbname" -v $DATABASE_DIR/$DB_SM $WORKING_DIR/sm.xml # db name for sm

xml ed -L -s "sm/user" -t elem -n "auto-create" $WORKING_DIR/sm.xml

xml ed -u "router/local/users" -v $WORKING_DIR/router-users.xml < $CONFIG_DIR/router.xml.dist > $WORKING_DIR/router.xml

xml ed -L -u "router/aci/filter" -v $WORKING_DIR/router-filter.xml $WORKING_DIR/router.xml

# change log configuration
xml ed -L -u "c2s/log/@type" -v "file" $WORKING_DIR/c2s.xml
xml ed -L -s "c2s/log" -t elem -n "file" $WORKING_DIR/c2s.xml
xml ed -L -u "c2s/log/file" -v $LOG_DIR/c2s.log $WORKING_DIR/c2s.xml

xml ed -L -u "router/log/@type" -v "file" $WORKING_DIR/router.xml
xml ed -L -s "router/log" -t elem -n "file" $WORKING_DIR/router.xml
xml ed -L -u "router/log/file" -v $LOG_DIR/router.log $WORKING_DIR/router.xml

xml ed -u "s2s/log/@type" -v "file" < $CONFIG_DIR/s2s.xml.dist > $WORKING_DIR/s2s.xml
xml ed -L -s "s2s/log" -t elem -n "file" $WORKING_DIR/s2s.xml
xml ed -L -u "s2s/log/file" -v $LOG_DIR/s2s.log $WORKING_DIR/s2s.xml

xml ed -L -u "sm/log/@type" -v "file" $WORKING_DIR/sm.xml
xml ed -L -s "sm/log" -t elem -n "file" $WORKING_DIR/sm.xml
xml ed -L -u "sm/log/file" -v $LOG_DIR/sm.log $WORKING_DIR/sm.xml

# change debug log configuration
xml ed -L -s "c2s/log" -t elem -n "debug" $WORKING_DIR/c2s.xml
xml ed -L -u "c2s/log/debug" -v $LOG_DIR/c2s-debug.log $WORKING_DIR/c2s.xml

xml ed -L -s "sm/log" -t elem -n "debug" $WORKING_DIR/sm.xml
xml ed -L -u "sm/log/debug" -v $LOG_DIR/sm-debug.log $WORKING_DIR/sm.xml

# change pid file
xml ed -L -u "c2s/pidfile" -v $PID_DIR/c2s.pid $WORKING_DIR/c2s.xml
xml ed -L -u "router/pidfile" -v $PID_DIR/router.pid $WORKING_DIR/router.xml
xml ed -L -u "s2s/pidfile" -v $PID_DIR/s2s.pid $WORKING_DIR/s2s.xml
xml ed -L -u "sm/pidfile" -v $PID_DIR/sm.pid $WORKING_DIR/sm.xml

# change port numbers
xml ed -L -u "c2s/router/port" -v $ROUTER_PORT $WORKING_DIR/c2s.xml
xml ed -L -u "c2s/local/port" -v $C2S_PORT $WORKING_DIR/c2s.xml
xml ed -L -u "sm/router/port" -v $ROUTER_PORT $WORKING_DIR/sm.xml
xml ed -L -u "router/local/port" -v $ROUTER_PORT $WORKING_DIR/router.xml
xml ed -L -u "s2s/router/port" -v $ROUTER_PORT $WORKING_DIR/s2s.xml
xml ed -L -u "s2s/local/port" -v $S2S_PORT $WORKING_DIR/s2s.xml

# edit jabberd.cfg file
sed "s|$CONFIG_DIR|$WORKING_DIR|g" < $CONFIG_DIR/jabberd.cfg.dist > $WORKING_DIR/jabberd.cfg

# copy needed files
cp $CONFIG_DIR/router-filter.xml.dist $WORKING_DIR/router-filter.xml
cp $CONFIG_DIR/router-users.xml.dist $WORKING_DIR/router-users.xml

# edit jabberd script and make it executable
sed "s|$CONFIG_DIR|$WORKING_DIR|g" < /usr/bin/jabberd > $WORKING_DIR/jabberd
chmod +x $WORKING_DIR/jabberd

# setup sqlite database
cd $DATABASE_DIR
echo -e "\ncreate databases..."

# create database for c2s
sqlite3 $DB_C2S < /usr/share/doc/packages/jabberd/db-setup.sqlite
chmod 666 $DB_C2S
# create database for sm
sqlite3 $DB_SM < /usr/share/doc/packages/jabberd/db-setup.sqlite
chmod 666 $DB_SM

# start jabberd in background
echo -e "\nstart jabberd in background..."

# wait and kill jabberd process in trap
trap '
echo "status of sm process: " `ps -p $SM_PID -o s | tail -1`
echo -e "wait to kill jabberd process $JABBERD_PID...\n"

while [ "`ps -p $SM_PID -o s | tail -1`" != "S" ]
do
        sleep 1
done

echo "status of sm process: " `ps -p $SM_PID -o s | tail -1`

echo "kill process $JABBERD_PID"
kill $JABBERD_PID
echo -e "\nprocess killed\n"' EXIT

$WORKING_DIR/jabberd &
# save pid of jabberd process
JABBERD_PID=$!

# wait until connection is ready
sleep 1
until test -f $LOG_DIR/c2s.log &&
	grep -q 'ready for connections' $LOG_DIR/c2s.log
do
        sleep 1
done

# save pid of session manager in order to clean up afterwards
SM_PID=`head -1 $WORKING_DIR/pid/sm.pid`

# test features

# create u users
echo -e "\ncreating test user..."
echo "port: $C2S_PORT"

userreg -h $MACHINEHOST -u $1 -p $C2S_PORT

sleep 1

# create u concurrent sessions
echo -e "\ncreate passive sessions"
pasvlogin -h $MACHINEHOST -u $1 -p $C2S_PORT | tee $PARENT_DIR/test.output
