#!/bin/sh

set -e

LISTBASE=liw-list
LISTDOMAIN=granny.liw.iki.fi
LISTNAME=${LISTBASE}@${LISTDOMAIN}

USERBASE=liw-user
USERDOMAIN=granny.liw.iki.fi
USERMBOX=benchmark-user.mbox

OWNER=liw@granny.liw.iki.fi

function clear_initial_state {
    rm -f benchmark-user.mbox
    rm -f benchmark-excess.mbox
    rm -f mlm.log
    rm -r $HOME/.enemies-of-carlotta
}

function create_list {
    enemies-of-carlotta --quiet --name=$LISTNAME --create --owner=$OWNER
}

function populate_with_subscribers {
    X="$1"
    i=0
    while [ $i -lt $X ]
    do
    	i=`expr $i + 1`
    	enemies-of-carlotta --quiet --name=$LISTNAME --subscribe \
	    $USERBASE-$i@$USERDOMAIN
    	case $i in
	*0) echo "Added $i initial subscribers so far..." ;;
	esac
    done
    echo "Added all $X initial subscribers."
}

function send_postings {
    Z="$1"
    i=0
    while [ $i -lt $Z ]
    do
    	i=`expr $i + 1`
    	echo "This is message $i." | mail -s "Messsage $i" $LISTNAME
    	case $i in
	*0) echo "Sent $i postings so far..." ;;
	esac
    done
    echo "Sent all $Z postings."
}

function check_postings {
    grep '^This is message' $USERMBOX | sort -n +3 | uniq -c | \
    awk -vZ=$1 \
    	'$1 != Z { print "Message", 0+$5, "has", $1, "postings, not", Z }'
}

function send_subscriptions {
    X="$1"
    Y="$2"
    N=`expr $X + $Y`
    i=0
    while [ $i -lt $Y ]
    do
    	i=`expr $i + 1`
	j=`expr $X + $i`
    	echo foo | \
	  mail -s foo $LISTBASE-subscribe-$USERBASE-$j=$USERDOMAIN@$LISTDOMAIN
    	case $i in
	*0) echo "Sent $i subscriptions so far..." ;;
	esac
    done
    echo "Sent all $Y subscriptions."
}

function check_subscriptions {
    awk -vX=$1 -v Y=$2 '
	/^From / { 
	    if (to && welcome) { count[to]++; n++; }
	    to = "" 
	    welcome = 0
	}
	/^To:/ { to = $2 }
	/^Subject: Welcome to/ { welcome = 1 }
	END {
	    if (to && welcome) { count[to]++; n++; }
	    for (to in count) {
	    	if (count[to] != 1)
		    print to, "subscribed", count[to], "times"
	    }
	    if (n != Y)
	    	print "Total", n, "subscriptions, wanted", Y
	}
	' $USERMBOX
}

function compute_times {
    X="$1"
    Y="$2"
    Z="$3"
    awk '
    	/^Subject: Messsage/ { msg = 1 }
	/^Subject: Welcome to/ { welcome = 1 }
	/^Date:/ { date = substr($0, 6) }
	/^From / && date {
	    if (msg) {
		if (!first_msg) first_msg = date; 
		else last_msg = date
	    } else if (welcome) {
		if (!first_welcome) first_welcome = date; 
		else last_welcome = date
	    }
	    msg = ""
	    welcome = 0
	    date = ""
	}
	END {
	    if (date) {
		if (msg) {
		    if (!first_msg) first_msg = date; 
		    else last_msg = date
		} else if (welcome) {
		    if (!first_welcome) first_welcome = date; 
		    else last_welcome = date
		}
	    }
	    print first_msg
	    print last_msg
	    print first_welcome
	    print last_welcome
	}
	' $USERMBOX | \
	(
	    read line; t1=`date --date="$line" +%s`
	    read line; t2=`date --date="$line" +%s`
	    read line; t3=`date --date="$line" +%s`
	    read line; t4=`date --date="$line" +%s`

	    echo "$X initial subscribers"
	    echo "$Z postings in `expr $t2 - $t1` seconds"
	    echo "$Y additional subscriptions in `expr $t4 - $t3` seconds"
	)
}

function file_size {
    if [ -f "$1" ]
    then
	du -b "$1" | awk '{ print $1 }'
    else
    	echo 0
    fi
}

function wait_for_idle {
    size=x
    newsize=`file_size $USERMBOX`
    while [ $size != $newsize ]
    do
    	echo "Waiting for processing to finish (mbox now $newsize bytes)..."
    	size=$newsize
    	sleep 10
	newsize=`file_size $USERMBOX`
    done
}

X="$1"
Y="$2"
Z="$3"

if [ -z "$X" -o -z "$Y" -o -z "$Z" ]
then
    echo "Usage: $0 initial-subscribers additional-subscribers postings" 1>&2
    exit 1
fi

clear_initial_state
create_list
populate_with_subscribers $X

send_postings $Z
wait_for_idle
send_subscriptions $X $Y
wait_for_idle

check_postings $Z
check_subscriptions $X $Y
compute_times $X $Y $Z

echo "Compressing and archiving mailbox, just a moment."
mv $USERMBOX $USERMBOX-$X-$Y-$Z
bzip2 $USERMBOX-$X-$Y-$Z
