#!/bin/bash
# Mircea Bardac, 2011

if test $# -ne 3; then
    echo "Usage: $0 <peers-directory> <measure-interval-start> <measure-interval-stop>"
    exit 1
fi

BRANCH=$(pwd)
TIME_START=$2
TIME_STOP=$3

PEERS_DIRECTORY=$1
mkdir -p $PEERS_DIRECTORY/output/
STATS_FILE=$PEERS_DIRECTORY/output/statistics.txt
> $STATS_FILE

echo "* Looking for errors printed on stderr..."
cd $PEERS_DIRECTORY/control

find . -regextype posix-egrep -regex '\./node.*\/output/[0-9]{5}\.err' | while read peer_file; do
    if test $(cat $peer_file | wc -l) -ne 0; then
        echo "*** $peer_file ***"
        cat $peer_file
        echo
    fi
done

echo "* Looking for errors and warnings on stdout..."
err_count=$(find . -regextype posix-egrep -regex '\./node.*\/output/[0-9]{5}\.out' | xargs cat | grep ^E | wc -l)
warn_count=$(find . -regextype posix-egrep -regex '\./node.*\/output/[0-9]{5}\.out' | xargs cat | grep ^W | wc -l)
echo "  * Errors: $err_count"
echo "  * Warnings: $warn_count"

NODE_COUNT=$(find . -type d -name 'node*' | wc -l)

cd $PEERS_DIRECTORY/

echo "* Counting number of peers that were executed..."
PEERS_COUNT=$(cat peer.count)
actual_count=$(find . -regextype posix-egrep -regex '\./[0-9]{5}\/output\/barter\.log' | wc -l)

if test $actual_count -ne $PEERS_COUNT; then
    echo
    echo "!!! ERROR !!!"
    echo "!!! We have counted $actual_count peers (expected $PEERS_COUNT peers). !!!"
fi

PEERS_PER_NODE=$[ $PEERS_COUNT / $NODE_COUNT ]


echo "* Counting number of delayed cycles (too much to process within a cycle)..."
c_ratio=0.0
t_cycles="(not-counted)"
d_cycles=$(find . -name 'barter.log' -exec cat {} \; | grep -e 'sleep[ ]*desync:f' | grep 'diff:f-' | wc -l)
if test $d_cycles -gt 0; then
    echo "  * Counting number of total cycles..."
    t_cycles=$(find . -name 'barter.log' -exec cat {} \; | grep -e 'sleep[ ]*desync:f' | wc -l)
    c_ratio=$(echo "scale=2; 100*${d_cycles}/${t_cycles}" | bc -l)
    echo "  * Delayed cycles: ${d_cycles}/${t_cycles} (${c_ratio}%)"
    sleep 2
fi

echo "* Extracting experiment parameters from community properties..."
sync_response_limit=$(grep community-property 00001/output/barter.log | grep :sync_response_limit | sed 's/.*value:i\([0-9]*\)/\1/g')
barter_history_size=$(grep community-property 00001/output/barter.log | grep :barter_history_size | sed 's/.*value:i\([0-9]*\)/\1/g')
barter_forward_record_on_creation=$(grep community-property 00001/output/barter.log | grep :barter_forward_record_on_creation | sed 's/.*value:b\([a-zA-Z]*\)/\1/g')

cycle_length_exp=$(grep community-property 00001/output/barter.log | grep :timestep | sed 's/.*value:f\([0-9]*\.[0-9]\)/\1/g')
cycle_length_real="600.00"

time_ratio=$(echo "scale=2; $cycle_length_real/$cycle_length_exp" | bc)

echo "* Summing up incoming and outgoing traffic..."
o=$(
find . -regextype posix-egrep -regex '\./[0-9]{5}\/output\/dispersy\.log' | while read f; do
    grep 's10:statistics' $f | tail -n 1 | sed 's/.*received:t2:.i[0-9]*, i\([0-9]*\).*send:t2:.i[0-9]*, i\([0-9]*\).*/\1 \2/g'
done | awk '{received += $1; sent += $2 } END { print received, sent }'
)
in_bytes=$(echo $o | cut -d' ' -f1)
out_bytes=$(echo $o | cut -d' ' -f2)

#cd $PEERS_DIRECTORY/control
#echo "* Summing up incoming traffic..."
#in_bytes=$(grep ^@\>in: * -R | awk '{sum += $2 } END { print sum }')
#echo "* Summing up outgoing traffic..."
#out_bytes=$(grep ^@\>out: * -R | awk '{sum += $2 } END { print sum }')
if test -z $in_bytes -o -z $out_bytes; then
    echo "* !!! No traffic statistics gathered!"
    lost_bytes=-1
    s_in_bytes="(not-counted)"
    s_out_bytes="(not-counted)"
    s_lost_bytes="(not-counted)"
    b_ratio='(unknown)'
    in_bytes=-1
    out_bytes=-1
else
    lost_bytes=$[ $out_bytes - $in_bytes ]
    s_in_bytes=$(printf %\'14d $in_bytes)
    s_out_bytes=$(printf %\'14d $out_bytes)
    s_lost_bytes=$(printf %\'14d $lost_bytes)
    b_ratio=$(echo "scale=2; 100*(${lost_bytes})/${out_bytes}" | bc -l)
fi

sig_req_timeouts=$(find . -name 'barter.log' | xargs cat | grep barter-community-signature-request-timeout | wc -l)

echo "* Counting number of signature request timeouts..."
s_ratio=0.0
total_sig_req="(not-counted)"
sig_req_timeouts=$(find . -name 'barter.log' | xargs cat | grep barter-community-signature-request-timeout | wc -l)
if test $sig_req_timeouts -gt 0; then
    echo "  * Counting number of total signature requests..."
    total_sig_req=$(find . -name 'dispersy.log' -exec cat {} \; | grep 'created-barter-record' | wc -l)
    s_ratio=$(echo "scale=2; 100*${sig_req_timeouts}/${total_sig_req}" | bc -l)
    echo "  * Signature request timeouts: ${sig_req_timeouts}/${total_sig_req} (${s_ratio}%)"
    sleep 2
fi


echo "* Extracting statistics..."

cd $BRANCH
./barter-extract-statistics $PEERS_DIRECTORY $TIME_START $TIME_STOP $time_ratio

echo "* Done"
echo
(
cat <<END-OF-MSG
Peers: $PEERS_COUNT
Nodes: $NODE_COUNT
Peers per node: $PEERS_PER_NODE

 Cycle length: $(printf %6.1f $cycle_length_exp) sec
Sync response: $(printf %6d $sync_response_limit) bytes

    Total sent traffic: $s_out_bytes bytes
Total received traffic: $s_in_bytes bytes
    Total lost traffic: $s_lost_bytes bytes ($b_ratio%)

END-OF-MSG
) >> $STATS_FILE

if test $d_cycles -gt 0; then
    echo "Delayed cycles: ${d_cycles}/${t_cycles} (${c_ratio}%)" >> $STATS_FILE
else
    echo "No delayed execution cycles." >> $STATS_FILE
fi

if test $sig_req_timeouts -gt 0; then
    echo "Signature request timeouts: ${sig_req_timeouts}/${total_sig_req} (${s_ratio}%)" >> $STATS_FILE
else
    echo "No signature request timeouts." >> $STATS_FILE
fi

svn_version=$(cat $PEERS_DIRECTORY/output/svn_version.txt)

(
cat <<END-OF-MSG
---
peers=$PEERS_COUNT
nodes=$NODE_COUNT
peers_per_node=$PEERS_PER_NODE
experiment_time_ratio=$time_ratio
cycle_length_experiment=$cycle_length_exp
cycle_length_real=$cycle_length_real
sync_member_count=$sync_member_count
sync_response_limit=$sync_response_limit
bytes_out=$out_bytes
bytes_in=$in_bytes
bytes_lost=$lost_bytes
bytes_lost_ratio=$b_ratio
total_cycles=$t_cycles
delayed_cycles=$d_cycles
delayed_cycles_ratio=$c_ratio
signature_request_timeouts=$sig_req_timeouts
signature_request_count=$total_sig_req
signature_request_timeout_ratio=$s_ratio
barter_history_size=$barter_history_size
barter_forward_record_on_creation=$barter_forward_record_on_creation
svn_version=$svn_version
END-OF-MSG
) >> $STATS_FILE

cat $PEERS_DIRECTORY/output/measure_info.txt >> $STATS_FILE
rm $PEERS_DIRECTORY/output/measure_info.txt

echo "=== Report ==="
cat $STATS_FILE
echo "=== end report ==="
echo