#!/bin/bash

###
### CHARTERINGMEASUREMENTS - Plot graphs about WG termination and chartering activity
###
### Version 1.0.0
###
### Written in 2009 by Jari Arkko
### Donated to the public domain.
###
### Changelog:
###
###   1.0.0   Initial version
###
### Usage:
###
###   charteringmeasurements [ --copy ]
###
### Options:
###
###   --copy              Copy results to arkko.com
###
###   --debug             Turn on debugging
###
###   --prefer-family=v4  
###

###
### Go to its own directory
###

rm -rf /tmp/cm
mkdir /tmp/cm
cd /tmp/cm

###
### Process args
###

DEBUG=0
COPY=0
PREFFAMILY=IPv6

while [ $# -gt 0 ]
do
  case $1 in
    --copy)      shift;
                 QUIET=1;;
    --debug)     shift;
                 DEBUG=1;;
    --prefer-family=IPv4)
                 shift;
                 PREFFAMILY=IPv4;;
    --prefer-family=IPv6)
                 shift;
                 PREFFAMILY=IPv6;;
    *)           echo 'Unrecognized argument ('$1') -- exit';
                 exit 1;;
  esac
done

###
### Set some variables
###

CURYEAR=`date +%Y`
CURMON=`date +%m`
CURDAY=`date +%d`

###
### Fetch known chartering events from the web (originally generated by
### admeasurements tool)
###

CHARTER=/tmp/cm/cm.charter-actions.txt
TERMINATION=/tmp/cm/cm.termination-actions.txt

rm -f $CHARTER $TERMINATION

wget -q --prefer-family=$PREFFAMILY \
     -O $CHARTER \
     http://www.arkko.com/tools/admeasurements/charter-actions.txt
wget -q --prefer-family=$PREFFAMILY \
     -O $TERMINATION \
     http://www.arkko.com/tools/admeasurements/termination-actions.txt

###
### FUNCTION: mapmonthnames
###

function mapmonthnames() {
  sed 's/:jan$/:1/
       s/:feb$/:2/
       s/:mar$/:3/
       s/:apr$/:4/
       s/:may$/:5/
       s/:jun$/:6/
       s/:jul$/:7/
       s/:aug$/:8/
       s/:sep$/:9/
       s/:oct$/:10/
       s/:nov$/:11/
       s/:dec$/:12/'
}

###
### FUNCTION: sortbyyear
###

function sortbyyear() {
  sort -n --key=4 --field-separator=:
}

###
### FUNCTION: summarizepertimeperiod
###

function summarizepertimeperiod() {
  awk -v period=$PERIOD -v curyear=$CURYEAR -v curmon=$CURMON '

function finishyear() {

  # Output an entry

  for (inperiod = 1; inperiod <= monthtoperiod(12); inperiod++) {
    printf("%d:%d:%d:%d:%d:%s\n",
           thisyear, inperiod,
           charter[inperiod], termination[inperiod], total[inperiod],
           wgs[inperiod]);
    if (thisyear == curyear && monthtoperiod(curmon) == inperiod) break;
  }

  # Reset values for next year

  resetvalues();
}

function resetvalues() {
  for (inperiod = 1; inperiod <= 12 / period; inperiod++) {
    total[inperiod] = 0;
    charter[inperiod] = 0;
    termination[inperiod] = 0;
    wgs[inperiod] = "";
  }
}

function monthtoperiod(month) {
  return(sprintf("%d",1 + (month - 1) / period));
}

BEGIN {
  FS = ":";
  thisyear = 0;
}

/.*/ {
  type = $1;
  wg = $2;
  ad = $3;
  year = $4;
  month = $5;

  if (thisyear == 0) {
    thisyear = year;
  } else if (year != thisyear) {
    finishyear();
    thisyear = year;
  }

  inperiod = monthtoperiod(month);
  total[inperiod]++;
  if (type == "recharter")
    charter[inperiod]++;
  else
    termination[inperiod]++;

  if (wgs[inperiod] == "")
    wgs[inperiod] = wg;
  else
    wgs[inperiod] = wgs[inperiod] "," wg;
}

END {
  if (thisyear != 0) finishyear();
}

'
}

###
### FUNCTION: extractgnuplotdata
###

function extractgnuplotdata() {
  awk -v period=$PERIOD '

BEGIN {
  FS = ":";
}

/.*/ {
  year = $1;
  inperiod = $2;
  charter = $3;
  terminate = $4;
  total = $5;
  wgs = $6;

  printf("%f\t%d\t%d\t%d\n",
         year + ((inperiod - 0.5) * period) / 12,
         charter, terminate, total);
}
'
}

###
### FUNCTION: makegnuplotfile
###

function makegnuplotfile() {
  base=$1;
  title="$2";
  datafile=${base}.dat;
  cmdfile=${base}.gnuplot;
  pngfile=${base}.png;

  if [ $DEBUG = 1 ]
  then
    echo m base = $base
    echo m title = $title
    echo m datafile = $datafile
    echo m cmdfile = $cmdfile
    echo m pngfile = $pngfile
  fi

  minyear=`cut -f1 -d. $datafile | sort -n | head -1`
  maxyear=`cut -f1 -d. $datafile | sort -n | tail -1`
  maxyear=`expr $maxyear + 1`
  if [ $PERIOD -gt 6 ]
  then
    TOP=70
  else
    if [ $PERIOD -gt 3 ]
    then
      TOP=45
    else
      TOP=30
    fi
  fi
  sed 's/TITLE/'"$title"'/g
       s/OUTPUT/'"$pngfile"'/g
       s/INPUT/'"$datafile"'/g
       s/TOP/'"$TOP"'/g
       s/MAX/'"$maxyear"'/g
       s/MIN/'"$minyear"'/g' > $cmdfile <<EOF
set title "TITLE"
set terminal png enhanced size 1000,580 xffffff x000000 x666666 xff9c6c x77ccdb x507e00 xc90000 x1200ff
set output 'OUTPUT'
set xlabel " "
set style fill solid 1.0 border -1
set boxwidth 0.7 relative
set style data histogram
set style histogram rows
set ylabel "# WGs"
set yrange [0:TOP]
set ytics 0,5,TOP
set y2tics 0,5,TOP
#set xrange [2003:2010]
#set xtics 2003.125,0.125,2009.875
set xtics ("Q1\n" 2003.125, "Q2\n    2003" 2003.375, "Q3\n" 2003.625, "Q4\n" 2003.875, \
           "Q1\n" 2004.125, "Q2\n    2004" 2004.375, "Q3\n" 2004.625, "Q4\n" 2004.875, \
           "Q1\n" 2005.125, "Q2\n    2005" 2005.375, "Q3\n" 2005.625, "Q4\n" 2005.875, \
           "Q1\n" 2006.125, "Q2\n    2006" 2006.375, "Q3\n" 2006.625, "Q4\n" 2006.875, \
           "Q1\n" 2007.125, "Q2\n    2007" 2007.375, "Q3\n" 2007.625, "Q4\n" 2007.875, \
           "Q1\n" 2008.125, "Q2\n    2008" 2008.375, "Q3\n" 2008.625, "Q4\n" 2008.875, \
           "Q1\n" 2009.125, "Q2\n    2009" 2009.375, "Q3\n" 2009.625, "Q4\n" 2009.875)
plot "INPUT" using 2 t 'Charter', \
     ''      using 3 t 'Terminate'
EOF
}

###
### FUNCTION: rungnuplot
###

function rungnuplot() {
  base=$1;
  title="$2";
  datafile=${base}.dat;
  cmdfile=${base}.gnuplot;
  pngfile=${base}.png;
  jpgfile=${base}.jpg;

  if [ $DEBUG = 1 ]
  then
    echo base = $base
    echo title = $title
    echo datafile = $datafile
    echo cmdfile = $cmdfile
    echo pngfile = $pngfile
    echo jpgfile = $jpgfile
  fi

  makegnuplotfile $base "$title"
  gnuplot < $cmdfile
  convert $pngfile $jpgfile
}

###
### Run the basic statistics
###

for PERIOD in 3 12
do
  cat $CHARTER $TERMINATION | 
  mapmonthnames | 
  sortbyyear | 
  summarizepertimeperiod $PERIOD > charteringstatistics${PERIOD}m.txt
done

###
### Produce Gnuplot graphs
###

for PERIOD in 3 12
do
  extractgnuplotdata < charteringstatistics${PERIOD}m.txt > charteringstatistics${PERIOD}m.dat
  rungnuplot charteringstatistics${PERIOD}m "WG creation and termination over ${PERIOD} month periods"
done

###
### Produce a web page
###

###
### Common awk functions
###

if [ $DEBUG -eq 1 ]
then
  echo 'charteringmeasurements: common functions...'
fi
COMMONFUNCS='
function initcommon() {
}

function stringtonumericdate(date) {
  split(date,datea,"-");
  year = datea[1] + 0;
  month = datea[2] + 0;
  day = datea[3] + 0;
  return(year + ((month-1+(day-1)/30) / 12.0));
}

function numericdatetostring(num) {
  year = sprintf("%d",num);
  num -= year;
  num *= 12;
  month = sprintf("%d",1 + num);
  num -= (month - 1);
  num *= 30;
  day = sprintf("%d",num);
  return(year "-" month "-" day);
}

function dateminus(d1,days) {
  x = stringtonumericdate(d1);
  x -= days / (12*30);
  return(numericdatetostring(x));
}

function datewithin(y1,m1,d1,gy,gm,gd,y2,m2,d2) {
  date1 = sprintf("%04d-%02d-%02d",y1,m1,d1);
  dateg = sprintf("%04d-%02d-%02d",gy,gm,gd);
  date2 = sprintf("%04d-%02d-%02d",y2,m2,d2);
  return(datele(date1,dateg) && datele(dateg,date2));
}

function datelt(d1,d2) {
  split(d1,d1a,"-");
  split(d2,d2a,"-");
  y1 = d1a[1] + 0;
  m1 = d1a[2] + 0;
  d1 = d1a[3] + 0;
  y2 = d2a[1] + 0;
  m2 = d2a[2] + 0;
  d2 = d2a[3] + 0;
  if (y1 < y2) return(1);
  if (y1 > y2) return(0);
  if (m1 < m2) return(1);
  if (m1 > m2) return(0);
  if (d1 < d2) return(1);
  if (d1 > d2) return(0);
  return(0);
}

function datele(d1,d2) {
  return(d1 == d2 || datelt(d1,d2));
}

function daydifference(d1,d2) {
  split(d1,d1a,"-");
  split(d2,d2a,"-");
  y1 = d1a[1] + 0;
  m1 = d1a[2] + 0;
  d1 = d1a[3] + 0;
  u1 = (y1 - 1970) * 365 + m1 * 30 + d1;
  y2 = d2a[1] + 0;
  m2 = d2a[2] + 0;
  d2 = d2a[3] + 0;
  u2 = (y2 - 1970) * 365 + m2 * 30 + d2;
  return(u1 - u2);
}

function getslogan_iesg() {
  return("You have to know how you are doing to improve");
}

function getslogan_lifecycle() {
  return("End-to-End Delay from draft-smith to an RFC");
}

function html_file_css_head(title,csshtmlfile,slogan) {
  csshtmlfileseensection[csshtmlfile] = 0;
  if (substr(csshtmlfile,1,5) != "/dev/") close(csshtmlfile);
  printf("<!DOCTYPE html PUBLIC %c-//W3C//DTD XHTML 1.0 Transitional//EN%c %chttp://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd%c>\n", 34, 34, 34, 34) > csshtmlfile;
  printf("<html xmlns=%chttp://www.w3.org/1999/xhtml%c xml:lang=%cen%c lang=%cen%c>\n",
         34, 34, 34, 34, 34, 34) >> csshtmlfile;
  printf("<head>\n") >> csshtmlfile;
  printf("<meta http-equiv=%cContent-Type%c content=%ctext/html;charset=utf-8%c />\n",
         34, 34, 34, 34) >> csshtmlfile;
  printf("<link href=%cadmeasurements.css%c rel=%cstylesheet%c type=%ctext/css%c />\n",
         34, 34, 34, 34, 34, 34) >> csshtmlfile;
  printf("<title>%s</title>\n", title) >> csshtmlfile;
  printf("</head>\n") >> csshtmlfile;
  printf("<body>\n") >> csshtmlfile;
  printf("<div class=%cpage%c>\n", 34, 34) >> csshtmlfile;
  printf("<table border=%c0%c width=%c100%%%c>\n", 34, 34, 34, 34) >> csshtmlfile;
  printf("<tbody>\n") >> csshtmlfile;
  printf("<tr><td class=%cwglist%c>\n", 34, 34) >> csshtmlfile;
  printf("   <a href=%chttp://tools.ietf.org%c><img class=%clogo%c alt=%cIETF%c src=%chttp://tools.ietf.org/images/ietflogo3h.png%c/></a><br/><br/>\n", 34, 34, 34, 34, 34, 34, 34, 34) >> csshtmlfile;
  printf("   <div class=%cmenuitem%c><a href=%chttp://www.ietf.org/%c>IETF Home</a></div>\n", 34, 34, 34, 34) >> csshtmlfile;
  printf("   <div class=%cmenuitem%c><a href=%chttp://tools.ietf.org/about%c>About Tools</a></div>\n", 34, 34, 34, 34) >> csshtmlfile;
  printf("   <div class=%cmenuitem%c><a href=%chttp://tools.ietf.org/dailydose%c>News</a></div>\n", 34, 34, 34, 34) >> csshtmlfile;
  printf("   <div class=%cmenuitem%c><a href=%chttp://tools.ietf.org/html/%c>Documents</a></div>\n", 34, 34, 34, 34) >> csshtmlfile;
  printf("   <br/>\n") >> csshtmlfile;
  printf("   <div class=%ctopitem%c><a href=%chttp://www.arkko.com/tools/stats.html%c>Statistics</a>:</div>\n", 34, 34, 34, 34) >> csshtmlfile;
  printf("   <div class=%cmenuitem%c>&nbsp; &nbsp; <a href=%chttp://www.arkko.com/tools/docstats.html%c>Docs</a></div>\n", 34, 34, 34, 34) >> csshtmlfile;
  printf("   <div class=%cmenuitem%c>&nbsp; &nbsp; <a href=%chttp://www.iana.org/about/performance/%c>IANA</a></div>\n", 34, 34, 34, 34) >> csshtmlfile;
  printf("   <div class=%cmenuitem%c>&nbsp; &nbsp; <a href=%chttp://www.arkko.com/tools/admeasurements/%c>IESG</a></div>\n", 34, 34, 34, 34) >> csshtmlfile;
  printf("   <div class=%cmenuitem%c>&nbsp; &nbsp; <a href=%chttp://www.arkko.com/tools/lifecyclestats.html%c>Lifecycle</a></div>\n", 34, 34, 34, 34) >> csshtmlfile;
  printf("   <div class=%cmenuitem%c>&nbsp; &nbsp; <a href=%chttp://www.arkko.com/tools/rfceditorstats.html%c>RFC Ed</a></div>\n", 34, 34, 34, 34) >> csshtmlfile;
  printf("   <div class=%cmenuitem%c>&nbsp; &nbsp; <a href=%chttp://rtg.ietf.org/~fenner/iesg/%c>Misc</a></div>\n", 34, 34, 34, 34) >> csshtmlfile;
  printf("</td>\n") >> csshtmlfile;
  printf("\n") >> csshtmlfile;
  printf("<td>\n") >> csshtmlfile;
  printf("\n") >> csshtmlfile;
  printf("<div class=%cadmeasurements%c>\n", 34, 34) >> csshtmlfile;
  printf("<div class=%cadmeasurements_banner%c>\n", 34, 34) >> csshtmlfile;
  printf("<h1>%s</h1>\n", title) >> csshtmlfile;
  printf("\n") >> csshtmlfile;
  printf("<div class=%cadmeasurements_slogan%c>\n", 34, 34) >> csshtmlfile;
  printf("&#8220;%s&#8221;\n", slogan) >> csshtmlfile;
  printf("</div><!-- admeasurements_slogan -->\n") >> csshtmlfile;
  printf("\n") >> csshtmlfile;
  printf("</div><!-- admeasurements_banner -->\n") >> csshtmlfile;
  printf("</div><!-- admeasurements -->\n") >> csshtmlfile;
  printf("\n") >> csshtmlfile;
  printf("<div class=%cadmeasurements%c>\n", 34, 34) >> csshtmlfile;
  printf("\n") >> csshtmlfile;
  printf("<table class=%cadmeasurements_columns%c>\n", 34, 34) >> csshtmlfile;
  printf("<tbody>\n") >> csshtmlfile;
  printf("<tr>\n") >> csshtmlfile;
  printf("<td class=%cadmeasurements_topic%c>\n", 34, 34) >> csshtmlfile;
}

function html_file_css_section(title,csshtmlfile) {
  if (csshtmlfileseensection[csshtmlfile] != 0) {
    printf("\n<div style=%cclear:both;padding:1px;%c></div>\n", 34, 34) >> csshtmlfile;
  }

  csshtmlfileseensection[csshtmlfile] = 1;

  printf("\n<h2>%s</h2>\n\n", title) >> csshtmlfile;
}

function html_file_css_section_nextcol(title,csshtmlfile) {
  csshtmlfileseensection[csshtmlfile] = 1;
  printf("\n</td>\n\n<td class=%cadmeasurements_topic%c>\n", 34, 34) >> csshtmlfile;
  printf("\n<h2>%s</h2>\n\n", title) >> csshtmlfile;
}

function html_file_css_end(htmlfile) {
  printf("</td>\n") >> htmlfile;
  printf("</tr>\n") >> htmlfile;
  printf("</tbody>\n") >> htmlfile;
  printf("</table><!-- admeasurements_columns -->\n") >> htmlfile;
  printf("</div><!-- admeasurements -->\n") >> htmlfile;
  printf("</td>\n") >> htmlfile;
  printf("</tr>\n") >> htmlfile;
  printf("</tbody>\n") >> htmlfile;
  printf("</table><!-- page -->\n") >> htmlfile;
  printf("</div><!-- page -->\n") >> htmlfile;
  printf("</body>\n") >> htmlfile;
  printf("</html>\n") >> htmlfile;
  close(htmlfile);
}

'

awk -v date="`date`" '

'"$COMMONFUNCS"'

BEGIN {
  initcommon();
  disclaimer = "Results have been produced by charteringmeasurements on " date ".";
}

END {

  activityhtml = "chartering-activity.html";
  html_file_css_head("Chartering Activity over Time",activityhtml,getslogan_iesg());
  html_file_css_section("Yearly Development",activityhtml);
  printf("<img src=%ccharteringstatistics12m.jpg%c style=%cborder:0%c alt=%crate%c>\n",
         34, 34, 34, 34, 34, 34) >> activityhtml;
  html_file_css_section("Quarterly Development",activityhtml);
  printf("<img src=%ccharteringstatistics3m.jpg%c style=%cborder:0%c alt=%crate%c>\n",
         34, 34, 34, 34, 34, 34) >> activityhtml;
  html_file_css_section("Data Freshness and Reliability",activityhtml);
  printf("%s\n", disclaimer) >> activityhtml;
  html_file_css_end(activityhtml);
  printf("<p>Page counts of <a href=%c%s%c>documents entering telechats</a> over time</p>\n",
         34, activityhtml, 34) >> "base.html";

}

' < /dev/null

###
### Copy results to arkko.com
###

scp -q *.jpg chartering-activity.html jarkko@users.piuha.net:public_html/tools/admeasurements/stat

###
### Clean-up
###

###
### End
###

exit 0
