#!/bin/bash

###
### DRAFTTIMELINE -- Draw a picture of draft timeline
###
###
### Version: 1.0.0, Jan 11th, 2008
###
### Usage
###
###   drafttimeline [options] draftname jpgfile
###                 initialindividualsubmission individualdays indname
###                 initialsubmission wgdays
###                 firstiesgstate iesgdays
###                 firstapprov rfceddays
###                 firstpub
###
###   where options is one of the following:
###
###   --versions                   Draw also version dates
###
###   --debug                      Turn on debugging
###
###   --prefer-family={IPv4,IPv6}  Select IP version preference for wget
###

###
### Parse command line
###

PREFFAMILY=IPv6
VERSIONS=0
DEBUG=0

while [ $# -gt 12 ]
do
  case $1 in
    --debug)
                shift;
                DEBUG=1;;
    --versions)
                shift;
                VERSIONS=1;;
    --prefer-family=IPv4)
                shift;
                PREFFAMILY=IPv4;;
    --prefer-family=IPv6)
                shift;
                PREFFAMILY=IPv6;;
    *)          echo 'drafttimeline: Unrecognized argument ('$1') -- exit';
                exit 1;;
  esac
done

if [ $# = 12 ]
then
  jpgfile="$2"
  inddraft="$5"
  draft="$1"
  begindate="$3"
  wgdate="$6"
  iesgdate="$8"
  approvdate=${10}
  enddate=${12}
  ageindividual=$4
  agewg="$7"
  ageiesg="$9"
  agerfced=${11}
else
  echo 'drafttimeline: wrong number of arguments ('$#', expected 12 -- exit'
  exit 1
fi

if [ x$inddraft = x -a $ageindividual = 0 ]
then
  case $draft in
    draft-ietf-*) ;;
    draft-iab-*)  ;;
    draft-iesg-*) ;;
    draft-irtf-*) ;;
    *) inddraft=$draft;
       ageindividual=$agewg;
       begindate=$wgdate;
       agewg=0;
       wgdate=none;;
  esac
fi

###
### Make some checks
###

if [ $ageindividual -lt 0 ]
then
  echo "warning: drafttimeline: Individual age negative for $draft -- exit"
  exit 1
fi

if [ $agewg -lt 0 ]
then
  echo "warning: drafttimeline: WG age negative for $draft -- exit"
  exit 1
fi

if [ $ageiesg -lt 0 ]
then
  echo "warning: drafttimeline: IESG age negative for $draft -- exit"
  exit 1
fi

if [ $agerfced -lt 0 ]
then
  echo "warning: drafttimeline: RFC Editor age negative for $draft -- exit"
  exit 1
fi

###
### Make temporary directory
###

tmpdir=/tmp/drafttimeline.$draft
rm -rf $tmpdir 2>&1 > /dev/null
mkdir $tmpdir

###
### Fixed picture constants
###

toty=400
totx=900
blockheight=70
xstart=15
ystart=15
yend=120
datesize=10
explainsize=12
versionsize=7
versionxoffset=`expr $versionsize + 2`
versionyoffset=-4
maxblock=`expr $totx - $xstart - $xstart - 100`

###
### Function: difference in days
###

function daydifference() {
  awk -v date1=$1 -v date2=$2 '

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);
}

END {
  printf("%s\n", daydifference(date1,date2));
}
' < /dev/null

}

###
### Function: revsmerge, merge revisions from the same day
###

function revsmerge() {
  
  sort -n |
  awk '
BEGIN {
  FS=":";
}

/:/ {
  ver = $1;
  date = $2;
  if (tab[date] == "") {
    tab[date] = ver;
  } else if (index(tab[date],ver) != 0) {
    # do not add anything
  } else {
    tab[date] = tab[date] "," ver;
  }
}

END {
  for (i in tab) {
    printf("%s:%s\n", tab[i], i);
  }
}
'
  
}

###
### Calculate some basic statistics
###

agetotal=`expr $ageindividual + $agewg + $ageiesg + $agerfced`
if [ $agetotal = 0 ]
then
  agetotal=1
fi
individual=`expr $maxblock \* $ageindividual / $agetotal`
wg=`expr $maxblock \* $agewg / $agetotal`
iesg=`expr $maxblock \* $ageiesg / $agetotal`
rfced=`expr $maxblock \* $agerfced / $agetotal`
persindividual=`(echo scale=1; echo 100 "*" $ageindividual / $agetotal) | bc`
perswg=`(echo scale=1; echo 100 "*" $agewg / $agetotal) | bc`
persiesg=`(echo scale=1; echo 100 "*" $ageiesg / $agetotal) | bc`
persrfced=`(echo scale=1; echo 100 "*" $agerfced / $agetotal) | bc`

#echo drafttimeline debug: ageindividual = $ageindividual >> /dev/stderr
#echo drafttimeline debug: agewg = $agewg >> /dev/stderr
#echo drafttimeline debug: ageiesg = $ageiesg >> /dev/stderr
#echo drafttimeline debug: agerfced = $agerfced >> /dev/stderr
#echo drafttimeline debug: agetotal = $agetotal >> /dev/stderr
#echo drafttimeline debug: wg = $wg >> /dev/stderr
#echo drafttimeline debug: iesg = $iesg >> /dev/stderr
#echo drafttimeline debug: rfced = $rfced >> /dev/stderr
#echo drafttimeline debug: persindividual = $persindividual >> /dev/stderr
#echo drafttimeline debug: perswg = $perswg >> /dev/stderr
#echo drafttimeline debug: persiesg = $persiesg >> /dev/stderr
#echo drafttimeline debug: persrfced = $persrfced >> /dev/stderr

###
### Create basic background tool images
###

#echo drafttimeline debug: basic images >> /dev/stderr

ppmmake black `expr $maxblock + 2` `expr $blockheight + 2` > $tmpdir/black.ppm
ppmmake black 1 `expr $blockheight` > $tmpdir/line.ppm

###
### Create the bars in the diagram
###

#echo drafttimeline debug: bars >> /dev/stderr

if [ $individual -gt 0 ]
then
  ppmmake grey `expr $individual - 1` $blockheight > $tmpdir/individual.ppm
fi

if [ $wg -gt 0 ]
then
  ppmmake lightblue `expr $wg - 1` $blockheight > $tmpdir/wg.ppm
fi

if [ $iesg -gt 0 ]
then
  ppmmake yellow `expr $iesg - 1` $blockheight > $tmpdir/iesg.ppm
fi

if [ $rfced -gt 0 ]
then
  ppmmake pink $rfced $blockheight > $tmpdir/rfced.ppm
fi

###
### Create image
###

#echo drafttimeline debug: image >> /dev/stderr

ppmmake white $totx $toty |
pnmpaste -replace $tmpdir/black.ppm `expr $xstart - 1` `expr $toty - $yend - $blockheight - 1` |

###
### Individual phase
###

if [ $individual -gt 0 ]
then
  #echo drafttimeline debug: individual >> /dev/stderr
  ppmlabel -angle 90 -size $datesize \
           -x `expr $xstart + $datesize` -y `expr $toty - $datesize` -colour black -text "$begindate" |
  pnmpaste -replace $tmpdir/individual.ppm $xstart `expr $toty - $yend - $blockheight` |
  ppmlabel -angle 45 -size $explainsize -color black \
           -x `expr $xstart + \( $individual / 2 \) - $explainsize` \
           -y `expr $toty - $yend - $blockheight - $explainsize` \
           -text "Individual draft" -text "  $inddraft" -text "    $ageindividual days ($persindividual%)"
else
  cat
fi |

###
### WG phase
###

if [ $wg -gt 0 ]
then
  #echo drafttimeline debug: wg >> /dev/stderr
  ppmlabel -angle 90 -size $datesize \
           -x `expr $xstart + $individual + $datesize / 2` -y `expr $toty - $datesize` \
           -colour black -text "$wgdate" |
  pnmpaste -replace $tmpdir/wg.ppm `expr $xstart + $individual` `expr $toty - $yend - $blockheight` |
  ppmlabel -angle 45 -size $explainsize -color black \
           -x `expr $xstart + $individual + \( $wg / 2 \) - $explainsize` \
           -y `expr $toty - $yend - $blockheight - $explainsize` \
           -text "WG draft" -text "  "$draft -text "    "$agewg" days ($perswg%)"
else
  cat
fi |

###
### IESG phase
###

if [ $iesg -gt 0 ]
then
  #echo drafttimeline debug: iesg >> /dev/stderr
  ppmlabel -angle 90 -size $datesize \
           -x `expr $xstart + $individual + $wg + $datesize / 2` -y `expr $toty - $datesize` \
           -colour black -text "$iesgdate" |
  pnmpaste -replace $tmpdir/iesg.ppm `expr $xstart + $individual + $wg` `expr $toty - $yend - $blockheight` |
  ppmlabel -angle 45 -size $explainsize -color black \
           -x `expr $xstart + $individual + $wg + \( $iesg / 2 \) - $explainsize` \
           -y `expr $toty - $yend - $blockheight - $explainsize` \
           -text "IESG processing" -text "  "$ageiesg" days ($persiesg%)"
else
  cat
fi |

###
### RFC Editor phase
###

if [ $rfced -gt 0 ]
then
  #echo drafttimeline debug: rfced >> /dev/stderr
  ppmlabel -angle 90 -size $datesize \
           -x `expr $xstart + $individual + $wg + $iesg + $datesize / 2` -y `expr $toty - $datesize` \
           -colour black -text "$approvdate" |
  pnmpaste -replace $tmpdir/rfced.ppm `expr $xstart + $individual + $wg + $iesg` `expr $toty - $yend - $blockheight` |
  ppmlabel -angle 45 -size $explainsize -color black \
           -x `expr $xstart + $individual + $wg + $iesg + \( $rfced / 2 \) - $explainsize` \
           -y `expr $toty - $yend - $blockheight - $explainsize` \
           -text "RFC Editor processing" -text "  "$agerfced" days ($persrfced%)"
else
  cat
fi |

###
### Publication
###

if [ $enddate = none ]
then
  cat
else
  #echo drafttimeline debug: publication >> /dev/stderr
  ppmlabel -angle 90 -size $datesize \
           -x `expr $xstart + $maxblock` -y `expr $toty - $datesize` \
           -colour black -text "$enddate"
fi |

###
### Add version bars and labels
###

if [ $VERSIONS = 1 ]
then
  cat > $tmpdir/beforeversion.ppm
  #echo drafttimeline debug: versions >> /dev/stderr
  revsfileorig=$tmpdir/revsorig.txt
  revsfile=$tmpdir/revs.txt
  docrevs --dates --prefer-family=$PREFFAMILY $draft | fgrep : > $revsfileorig
  if [ x$inddraft = x ]
  then
    nop=nop
  else
    docrevs --dates --prefer-family=$PREFFAMILY $inddraft | fgrep : >> $revsfileorig
  fi
  revsmerge < $revsfileorig > $revsfile
  for item in `cat $revsfile`
  do
    version=`echo $item | cut -f1 -d:`
    date=`echo $item | cut -f2 -d:`
    #echo "drafttimeline debug: for $draft, -$version appeared at $date" >> /dev/stderr
    if [ $date = UNKNOWN ]
    then
      nop=nop
    else
      days=`daydifference $date $begindate`
      daypixels=`expr $maxblock \* $days / $agetotal`
      #echo "drafttimeline debug: which is $days days and $daypixels pixels" >> /dev/stderr
      if [ $daypixels -ge 0 -a $daypixels -le $maxblock ]
      then
        cat $tmpdir/beforeversion.ppm |
        pnmpaste -replace $tmpdir/line.ppm `expr $xstart + $daypixels` `expr $toty - $yend - $blockheight` |
        ppmlabel -size $versionsize -color black -angle 90 \
                 -x `expr $xstart + $daypixels + $versionxoffset` \
                 -y `expr $toty - $yend - $versionsize - $versionyoffset` \
                 -text "$version" |
        cat > $tmpdir/afterversion.ppm
        cp $tmpdir/afterversion.ppm $tmpdir/beforeversion.ppm
      else
        echo "drafttimeline: $draft revision $version date is outside bounds" >> /dev/stderr
      fi
    fi
  done
  cat $tmpdir/beforeversion.ppm
else
  cat
fi |

###
### Finalize
###

pnmmargin -white 1 |
pnmtojpeg > $jpgfile

#echo drafttimeline debug: finalize >> /dev/stderr

###
### Cleanup
###

rm -rf $tmpdir 2>&1 > /dev/null
