#!/usr/bin/env bash
# VICIfast Research, Report 01: The Two Bottlenecks Inside a Busy VICIdial Server
# Test harness. FOR A TEST SERVER, NOT A LIVE FLOOR. Read it before you run it.
# Read-only sampler of the AMI router, Asterisk CPU and VICIdial call health over one
# window.
#
# usage (via env): LABEL=.. REP=<n reporter loops> SECS=<window seconds>
set +e
DB=$(awk -F'=> *' '/^VARDB_database/{print $2}' /etc/astguiclient.conf | tr -d ' \r')
W=/root/vf-engine-ab; mkdir -p $W; M="mysql -N $DB"
stat(){ mysql -N -e "show global status like 'Table_locks_waited'" | awk '{print $2}'; }
# reporter: a stats-agent style read — 7 days of vicidial_log by user and hour, plus lead counts by status
rep(){ while [ -f $W/run.$LABEL ]; do s=$(date +%s.%N)
  $M -e "select user, hour(call_date) h, count(*), avg(length_in_sec), sum(status='SALE') from vicidial_log where call_date >= curdate() - interval 7 day group by user, h" >/dev/null
  $M -e "select status, called_since_last_reset, count(*) from vicidial_list group by status, called_since_last_reset" >/dev/null
  echo "$(date +%s.%N) - $s" | bc >> $W/rep.$LABEL; done; }
rm -f $W/rep.$LABEL $W/samp.$LABEL; touch $W/run.$LABEL
t0=$(date '+%F %T'); lw0=$(stat)
for i in $(seq 1 $REP); do rep & done
end=$(( $(date +%s) + SECS ))
while [ $(date +%s) -lt $end ]; do
  mysql -N -e "select
     (select count(*) from information_schema.processlist where state='Waiting for table level lock' and user not in ('root','system user')),
     (select coalesce(max(time),0) from information_schema.processlist where state='Waiting for table level lock' and user not in ('root','system user')),
     (select count(*) from information_schema.innodb_trx where trx_state='LOCK WAIT'),
     (select count(*) from information_schema.processlist where command='Query' and time>=1 and user not in ('root','system user')),
     (select count(*) from $DB.vicidial_live_agents where status in ('READY','CLOSER'))" >> $W/samp.$LABEL
  sleep 0.5
done
rm -f $W/run.$LABEL; wait
t1=$(date '+%F %T'); lw1=$(stat)
read calls drops < <($M -e "select count(*), sum(status='DROP') from vicidial_log where call_date between '$t0' and '$t1'")
read icalls idrops < <($M -e "select count(*), sum(status='DROP') from vicidial_closer_log where call_date between '$t0' and '$t1'")
awk -v L=$LABEL -v S=$SECS -v lw=$((lw1-lw0)) -v c=$calls -v d=${drops:-0} -v ic=$icalls -v id=${idrops:-0} '
 {n++; a+=$1; if($1>ma)ma=$1; if($2>mt)mt=$2; iw+=$3; if($3>mi)mi=$3; s1+=$4; if($4>m1)m1=$4; fr+=$5}
 END{printf "%-12s %3ds | waiting-on-table-lock avg %.1f max %d, longest %ds | innodb row-lock waits avg %.1f max %d | VICIdial stmts >=1s avg %.1f max %d | lock waits/s %.1f | out %d drop %d (%.1f%%) | in %d drop %d | free agents avg %.1f\n",
  L,S,a/n,ma,mt,iw/n,mi,s1/n,m1,lw/S,c,d,(c?100*d/c:0),ic,id,fr/n}' $W/samp.$LABEL
[ -s $W/rep.$LABEL ] && awk '{n++;s+=$1;if($1>m)m=$1} END{printf "             reporter runs %d, avg %.2fs, max %.2fs\n",n,s/n,m}' $W/rep.$LABEL
