#!/bin/bash

###
### DOCAGE -- Get Internet Draft initial submission date
###
### Usage
###
###   docage [options] draftname
###
###   where options is one of the following:
###
###   --debug
###
###   --version nn
###
###   --expires
###
###   --replaces
###
###   --prefer-family={IPv4,IPv6}
###

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

DEBUG=0
PREFFAMILY=IPv6
TRACKREPLACES=0
TRACKEXPIRES=0
VERSION=00

#echo 'docage: debug: calling docage with' $* '...' >> /tmp/docagecalls.txt

while [ $# -gt 1 ]
do
  case $1 in
    --debug)
                shift;
                DEBUG=1;;
    --replaces)
                shift;
                TRACKREPLACES=1;;
    --expires)
                shift;
                TRACKEXPIRES=1;;
    --version)
                shift;
                VERSION=$1;
                shift;;
    --prefer-family=IPv4)
                shift;
                PREFFAMILY=IPv4;;
    --prefer-family=IPv6)
                shift;
                PREFFAMILY=IPv6;;
    *)          echo 'docage: Unrecognized argument ('$1') -- exit' >> /dev/stderr;
                exit 1;;
  esac
done
if [ $# -gt 0 ]
then
  initialdocname=`echo "$1" |
                  #sed 's/-[0-9][0-9]\$//' |
                  sed 's/-[0-9][0-9][.]txt\$//'`
  docname=$initialdocname
else
  echo "docage: usage docname [options] draftname" >> /dev/stderr
  exit 1
fi

###
### Set variables for fetching the information, temporary directories, etc.
###

cachedir=$HOME/IETF/newdb/real/history-i-d
wgetcachedir=$HOME/Tmp/docage.wgetcache
WGETOPTS="--prefer-family="$PREFFAMILY" -q --timeout=20"
#WGETOPTS="--prefer-family="$PREFFAMILY
tmpdir=/tmp/docage.$docname
rm -rf $tmpdir 2>&1 > /dev/null
mkdir $tmpdir
mkdir -p $wgetcachedir 2>&1 > /dev/null

###
### Get configuration data from the docage.data file
###

datafile=`echo $0 | sed s/docage/docage.data/`
if [ -s $datafile ]
then
  nop=ok
else
  echo 'docage: Fatal error: No data file ('$datafile') exists -- exit'
  rm -rf $tmpdir 2>&1 > /dev/null
  exit 1
fi

###
### Function: caching wget
###

function wgetcached() (

  outputfile=$1;
  url=$2;
  urlmapped=$wgetcachedir/`echo $url | tr /: -_`

  #
  # Clean cache every day
  #

  dnow=`date +%Y-%m-%d`
  if [ -s $wgetcachedir/creation -a x"$dnow" = x`cat $wgetcachedir/creation 2> /dev/null` ]
  then
    if [ $DEBUG = 1 ]; then echo "docage: cache age ok"; fi
    nop=nop
  else
    if [ $DEBUG = 1 ]; then echo "docage: cleaning cache"; fi
    rm -rf $wgetcachedir 2>&1 > /dev/null
    mkdir -p $wgetcachedir 2>&1 > /dev/null
    echo $dnow > $wgetcachedir/creation
  fi

  #
  # See if file is in cache
  #

  if [ -s $urlmapped ]
  then
    if [ $DEBUG = 1 ]; then echo "docage: file can be found from cache $urlmapped"; fi
    ln -s $urlmapped $outputfile
    exit 1
  else
    if [ $DEBUG = 1 ]; then echo "docage: file cannot be found, wgetting $url"; fi
    if wget $WGETOPTS -O $outputfile $url
    then
      if [ $DEBUG = 1 ]; then echo "docage: wget success, copy"; fi
      cp $outputfile $urlmapped
      exit 1
    else
      if [ $DEBUG = 1 ]; then echo "docage: wget failure"; fi
      exit 0
    fi
  fi
)

###
### Function: fetch a draft
###

function draftget() {

  draftfiletostore=$1;
  drafturlbasetoget=$2;
  drafturltoget=$3;

  cachefile=$cachedir/$drafturltoget

  if [ -f $cachefile -a -s $cachefile ]
  then
    if [ $DEBUG = 1 ]
    then
      echo 'docage: debug: no need to fetch '$drafturltoget', already in cache '$cachefile >> /dev/stderr
    fi
    ln -s $cachefile $draftfiletostore
  else
    if [ $DEBUG = 1 ]
    then
      echo 'docage: debug: Must fetch '$drafturltoget', not in cache '$cachedir >> /dev/stderr
    fi
    wget $WGETOPTS -O $draftfiletostore $drafturlbasetoget$drafturltoget
  fi
}

###
### Check if the draft is one of the special cases that never existed (or there is no archive)
###

if fgrep doesnotexist:$docname $datafile > /dev/null
then
  echo "docage: Document $docname is not in the archives at all -- exit" >> /dev/stderr;
  rm -rf $tmpdir 2>&1 > /dev/null
  exit 1
fi

correctname=`fgrep wrongname:$docname: $datafile | cut -f3 -d: | head -1`
if [ x$correctname = x ]
then
  nop=nop
else
  docname=$correctname
fi

###
### Fetch data from the tools system
###

while [ x = x ]
do

  #
  # Fetch the document information from tools.ietf.org
  #

  baseurl="http://merlot.tools.ietf.org/draft/$docname/state"
  tmpfile=$tmpdir/$docname.state
  if [ $DEBUG = 1 ]
  then
    echo 'docage debug: Fetching document '$docname' information...' >> /dev/stderr
  fi
  if wgetcached $tmpfile $baseurl
  then
    nop=nop
  else
    #echo "docage: wget failure in info fetch for $docname -- exit" >> /dev/stderr
    #rm -rf $tmpdir 2>&1 > /dev/null
    touch $tmpfile
  fi

  #
  # Is this draft replacing an earlier draft?
  #

  if [ $TRACKREPLACES = 0 ]
  then
    replacesdoc=''
  else

    # 
    # Check from the tools database
    #

    replacesdoc=`grep '^Doc-replaces: ' $tmpfile |
                 head -1 |
                 cut -f2 -d: |
                 cut -f1 -d';' |
                 tr -d ' '`

    #
    # If no info, check from local extra information file
    #

    if [ x$replacesdoc = x ]
    then
      replacesdoc=`fgrep replacedby:$docname: $datafile | cut -f3 -d: | head -1`
    fi
    if [ $DEBUG = 1 ]
    then
      if [ x$replacesdoc = x ]
      then
        echo 'docage debug: This document does not replace any earlier documents ' >> /dev/stderr
      else
        echo 'docage debug: This document replaces earlier documents '$replacesdoc >> /dev/stderr
      fi
    fi
  fi

  #
  # If not, report initial submission date
  # If yes, keep searching
  #

  if [ x"$replacesdoc" = x ]
  then
    initialday=`grep '^Doc-created: ' $tmpfile |
                cut -f2 -d: |
                cut -f1 -d';' |
                tr -d ' '`

    #
    # If initial day is not in the database, use getauthors
    #

    if [ x$initialday = x -o $VERSION -gt 0 ]
    then
      rev=`grep "^firstknownrevision:$docname:" $datafile | cut -f3 -d:`
      if [ $DEBUG = 1 ]
      then
        echo 'docage debug: Checking first revision, rev = '$rev >> /dev/stderr
      fi
      if [ x$rev = x ]
      then
        rev=$VERSION
      else
        if [ $VERSION -ge $rev ]
        then
          rev=$VERSION
        else
          echo 'docage: Warning: No information about version '$VERSION' is available for '$docname >> /dev/stderr
        fi
      fi
      if [ $DEBUG = 1 ]
      then
        echo 'docage debug: No document creation information in the database, fetching '$docname'-'$rev'.txt...' >> /dev/stderr
      fi
      draftfile=$tmpdir/$docname-$rev.txt
      renameddocname=`grep "^renamedby:$docname:" $datafile | cut -f3 -d:`
      drafturlbase=http://tools.ietf.org/id/
      if [ x$renameddocname = x ]
      then
        drafturl=$docname-$rev.txt
      else
        drafturl=$renameddocname-$rev.txt
      fi
      if draftget $draftfile $drafturlbase $drafturl
      then
        nop=nop
      else
        echo "docage: wget failure in draft $docname revision $rev fetch -- exit" >> /dev/stderr
        rm -rf $tmpdir 2>&1 > /dev/null
        exit 1;
      fi

      #
      # Check that the draft type is right (not a tombstone)
      #

      docdata=$tmpdir/$docname.getauthors
      if [ $DEBUG = 1 ]
      then
        echo 'docage debug: Using getidtype (cmd: 'getidtype $draftfile')...' >> /dev/stderr
      fi
      getidresult=`getidtype $draftfile | cut -f2 -d:`
      if [ $DEBUG = 1 ]
      then
        echo 'docage debug: Getidtype result is '$getidresult'...' >> /dev/stderr
      fi
      if [ x$getidresult = xexists ]
      then

        #
        # Ok. Use getauthors.
        #

        if [ $DEBUG = 1 ]
        then
          echo 'docage debug: Using getauthors...' >> /dev/stderr
        fi
        if getauthors --dateonly $draftfile > $docdata
        then
          nop=nop
        else
          echo 'docage: getauthors failure -- exit' >> /dev/stderr
          rm -rf $tmpdir 2>&1 > /dev/null
          exit 1;
        fi

      else

        #
        # Getting desperate. See if the tools eventsfile has the information
        #

        if [ $DEBUG = 1 ]
        then
          echo 'docage debug: Using events file...' >> /dev/stderr
        fi
        eventsurl="http://tools.ietf.org/draft/$docname/events"
        eventsfile="$tmpdir/$docname.events"
        if wgetcached $eventsfile $eventsurl
        then
          pureeventsfile=$tmpdir/$docname.revevents;
          awk '
/ docrev=.[0-9][0-9]. docsubmitted=.[0-9]+-[0-9]+-[0-9]+. / {
  x = substr($0,"docrev=");
  split(x,comps,sprintf("%c",39));
  printf("%02d:%s\n", comps[2], comps[4]);
}' < $eventsfile |
          sort -u > $pureeventsfile
          date=`grep "^${rev}:" $pureeventsfile | cut -f2 -d: | tail -1`
          if [ $DEBUG = 1 ]
          then
            echo 'docage debug: date result is '$date'...' >> /dev/stderr
          fi
          if [ x$date = x ] 
          then
            if [ $DEBUG = 1 ]
            then
              echo 'docage debug: exit case...' >> /dev/stderr
            fi
            echo 'docage: type of draft '$docname' is wrong and events file has no information -- exit' >> /dev/stderr
            rm -rf $tmpdir 2>&1 > /dev/null
            exit 1;
          else
            if [ $DEBUG = 1 ]
            then
              echo 'docage debug: Events file has the information '$date'...' >> /dev/stderr
            fi
            year=`echo $date | cut -f1 -d-`
            monthnum=`echo $date | cut -f2 -d-`
            month=`echo jan:feb:mar:apr:may:jun:jul:aug:sep:oct:nov:dec | cut -d: -f$monthnum`
            day=`echo $date | cut -f3 -d-`
            echo x:x:x:x:x:x:$month:$year > $docdata
          fi
        else
          if [ $DEBUG = 1 ]
          then
            echo 'docage debug: exit case 2...' >> /dev/stderr
          fi
          echo 'docage: type of draft '$docname' is wrong and no events file -- exit' >> /dev/stderr
          rm -rf $tmpdir 2>&1 > /dev/null
          exit 1;
        fi

      fi

      #
      # See if getauthors succeeded
      #

      if fgrep :UNRECOGNIZED $docdata > /dev/null
      then
        echo 'docage: getauthors does not recognize draft '$docname'-$rev.txt -- exit' >> /dev/stderr
        rm -rf $tmpdir 2>&1 > /dev/null
        exit 1;
      fi
      month=`cut -f7 -d: $docdata | head -1`
      year=`cut -f8 -d: $docdata | head -1`
      day=`cut -f9 -d: $docdata | head -1`
      if [ $DEBUG = 1 ]
      then
        echo 'docage debug: year = '$year', month = '$month', day = '$day >> /dev/stderr
      fi
      if [ $day = UNKNOWN ]
      then
        if [ $DEBUG = 1 ]
        then
          echo 'docage debug: getauthors unable to give us the day, assuming 1st...' >> /dev/stderr
        fi
        day=1
      fi
      if [ $month = UNKNOWN -o $year = UNKNOWN ]
      then
        echo 'docage: getauthors does not recognize submission time in '$docname'-'$rev'.txt -- exit' >> /dev/stderr
        rm -rf $tmpdir 2>&1 > /dev/null
        exit 1;
      fi
 
      #
      # Getauthors did succeed -- now use the time from there (and guess day of month)
      #

      case $month in
        jan) monthnum=1;;
        feb) monthnum=2;;
        mar) monthnum=3;;
        apr) monthnum=4;;
        may) monthnum=5;;
        jun) monthnum=6;;
        jul) monthnum=7;;
        aug) monthnum=8;;
        sep) monthnum=9;;
        oct) monthnum=10;;
        nov) monthnum=11;;
        dec) monthnum=12;;
        *)   echo 'docage: getauthors month name '$month' is unrecognized -- exit' >> /dev/stderr
             rm -rf $tmpdir 2>&1 > /dev/null
             exit 1;;
      esac
      initialday=$year'-'$monthnum'-'$day
    fi

    #
    # If we need information about expiration date, find it out
    #

    if [ $TRACKEXPIRES = 1 ]
    then
      if fgrep 'Doc-validity: Expired' $tmpfile > /dev/null
      then
        expired=1
        if [ $DEBUG = 1 ]
        then
          echo 'docage debug: draft has expired' >> /dev/stderr
        fi
        finalsubmissionday=`grep '^Doc-submitted: ' $tmpfile |
                            cut -f2 -d: |
                            cut -f1 -d';' |
                            tr -d ' '`
        if [ $DEBUG = 1 ]
        then
          echo 'docage debug: last submission date = '$finalsubmissionday >> /dev/stderr
        fi
        if [ "x$finalsubmissionday" = x ]
        then
          expirydate=none
          echo 'docage: Warning: No submission date available for expired draft '$docname >> /dev/stderr
        else
          expyear=`echo $finalsubmissionday | cut -f1 -d-`
          expmonthnum=`echo $finalsubmissionday | cut -f2 -d-`
          expday=`echo $finalsubmissionday | cut -f3 -d-`
          expmonthnum=`expr $expmonthnum + 6`
          if [ $expmonthnum -gt 12 ]
          then
            expmonthnum=`expr $expmonthnum - 12`
            expyear=`expr $expyear + 1`
          fi
          expirydate=$expyear-$expmonthnum-$expday
        fi
      else
        expired=0
        if [ $DEBUG = 1 ]
        then
          echo 'docage debug: draft has not expired' >> /dev/stderr
        fi
      fi
    fi
    
    #
    # Output the result
    #

    if [ $docname = $initialdocname ]
    then
      echo $initialday
    else
      echo $initialday:$docname
    fi
    if [ $TRACKEXPIRES = 1 ]
    then
      if [ $expired = 1 ]
      then
        echo $expirydate
      else
        echo none
      fi
    fi
    rm -rf $tmpdir 2>&1 > /dev/null
    exit 0

  else

    docname=$replacesdoc
    continue

  fi

done

###
### Cleanup
###

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