#!/bin/sh
#
# Script to make entering and progressing issues easier.
#
# The issues are contained in an issues.db file, as a sequence of lines of
# tab-separated fields:
#
#   - one-line description
#   - resolution
#   - reference mail thread (preferrably a URL)
#   - raised on (date)
#   - resolved on (date)
#   - specification up-to-date?
#   - issue number
#

USAGE="issues-db <issues-db> <html-src>"

if [ $# -lt 2 ]
then
   echo $USAGE; exit 1;
fi

ISSUES=$1; shift
HTML=build/$2; shift
#DATEFRM="+%d %b %Y"
DATEFRM="+%Y-%m-%d"
TMP=${TMPDIR:-/tmp}/issue.$$
ARCH=`uname`
PAGER=${PAGER:-more}


pr ()
{
  if [ $ARCH = "Linux" ]; then
    echo -e "$*"
  else
    echo "$*"
  fi
}

prn ()
{
  if [ $ARCH = "Linux" ]; then
    echo -e "$* \c"
  else
    echo "$*\c"
  fi
}


quick_help ()
{
  pr
  pr "\tThis program updates $ISSUES and $HTML"
  pr
  pr "\tTo see the issues (plain text):    issues -l"
  pr "\tTo see the issues (HTML table):    issues -g"
  pr "\tTo see the unresolved issues:      issues -t"
  pr "\tTo see issues yet to be updated:   issues -y"
  pr "\tTo enter a new issue:              issues -a [reference [description]]"
  pr "\tTo resolve an issue:               issues -r [number [resolution-text]]"
  pr "\tTo mark the spec as up-to-date:    issues -u [number]"
  pr "\tTo be prompted for all arguments:  issue"
  pr "\tTo get quick help:                 issues -?"
  pr
  pr "\tYou'll be prompted for all missing arguments"
  pr
}

list_issues ()
{
  (
    IFS='	'
    #num=0
    while read desc res ref date1 date2 spec num; do
      #num=`expr $num + 1`
      pr "Number          : $num"
      pr "Description     : $desc"
      pr "Resolution      : $res"
      pr "Reference       : $ref"
      pr "Archived on     : $date1"
      pr "Resolved on     : $date2"
      pr "Spec up-to-date : $spec"
      pr
    done
  ) < $ISSUES
}

list_unresolved ()
{
  (
    IFS='	'
    #num=0
    while read desc res ref date1 date2 spec num; do
      #num=`expr $num + 1`
      if [ "$res" = "-" ]; then
	pr "Number          : $num"
	pr "Description     : $desc"
	pr "Resolution      : $res"
	pr "Reference       : $ref"
	pr "Archived on     : $date1"
	pr "Resolved on     : $date2"
	pr "Spec up-to-date : $spec"
	pr
      fi
    done
  ) < $ISSUES
}

list_to_be_updated ()
{
  (
    IFS='	'
    #num=0
    while read desc res ref date1 date2 spec num; do
      #num=`expr $num + 1`
      if [ "$spec" = "no" ]; then
	pr "Number          : $num"
	pr "Description     : $desc"
	pr "Resolution      : $res"
	pr "Reference       : $ref"
	pr "Archived on     : $date1"
	pr "Resolved on     : $date2"
	pr "Spec up-to-date : $spec"
	pr
      fi
    done
  ) < $ISSUES
}

generate_html ()
{
  echo "<table border>"
  echo "<tr>"
  echo "  <th>#"
  echo "  <th>Description"
  echo "  <th>Resolution"
  echo "  <th>Reference"
  echo "  <th>Archived&nbsp;on"
  echo "  <th>Resolved&nbsp;on"
  echo "  <th>Spec up-to-date?"
  sort -r -t '	' -k 5,6 -k 7,8nr $ISSUES |
  (
    IFS='	'
    #i=0
    while read desc res ref date1 date2 spec i; do
      #i=`expr $i + 1`
      if [ "$res" = "-" ]; then
	class=unresolved
      else
	class=resolved
      fi
      echo "<tr valign=baseline class=$class>"
      echo "  <td>$i"
      echo "  <td>$desc"
      echo "  <td>$res"
      case "$ref" in
	http:* | ftp:*) echo "  <td><a href='$ref'>here</a>";;
	*)      echo "  <td>$ref";;
      esac

      echo "  <td>$date1"
      echo "  <td>$date2"
      echo "  <td>$spec"
    done
  )
  pr "</table>"
  pr "<p>Last update: "`ls -l $ISSUES | cut -c 42-48`\
   " (HTML version generated: "`date "$DATEFRM"`")"

}

add_issue ()
{
  if [ -z "$ref" ]; then
    prn "Reference (URL): "
    read ref
  fi
  if [ -z "$desc" ]; then
    prn "Description: "
    read desc
  fi
  ref=`echo $ref | tr "&	" "  "`
  desc=`echo $desc | tr "&	" "  "`
  num=`wc -l $ISSUES|cut -c -8`
  num=`expr $num + 1`
  pr "$desc	-	$ref	"`date "$DATEFRM"`"	not yet	no	$num" >>$ISSUES
  generate_html >$HTML
}

resolve_issue ()
{
  if [ -z "$num" ]; then
    prn "Number: "
    read num
  fi
  case "$num" in
    [0-9] | [0-9][0-9] | [0-9][0-9][0-9] | [0-9][0-9][0-9][0-9]) ;;
    *) pr "Error: not a valid issue number: $num" >&2; return 2;;
  esac
  if [ -z "$res" ]; then
    prn "Resolution: "
    read res
  fi
  res=`echo $res | tr "&	" "  "`
  date=`date "$DATEFRM"`
  (
    IFS='	'
    #i=0
    while read desc h1 ref date1 h2 spec i; do
      #i=`expr $i + 1`
      if [ $i = "$num" ]; then
	echo "$desc	$res	$ref	$date1	$date	$spec	$i"
      else
	echo "$desc	$h1	$ref	$date1	$h2	$spec	$i"
      fi
    done < $ISSUES >$TMP
  )
  mv $TMP $ISSUES
  generate_html >$HTML
}

update_issue ()
{
  if [ -z "$num" ]; then
    prn "Number: "
    read num
  fi
  case "$num" in
    [0-9] | [0-9][0-9] | [0-9][0-9][0-9] | [0-9][0-9][0-9][0-9]) ;;
    *) pr "Error: not a valid issue number: $num" >&2; return 2;;
  esac
  (
    IFS='	'
    #i=0
    while read desc res ref date1 date2 spec i; do
      #i=`expr $i + 1`
      if [ $i != "$num" ]; then
	echo "$desc	$res	$ref	$date1	$date2	$spec	$i"
      elif [ "$res" = "-" ]; then
	pr "Error: cannot update; the issue must be resolved first" >&2
	echo "$desc	$res	$ref	$date1	$date2	$spec	$i"
      else
	echo "$desc	$res	$ref	$date1	$date2	yes	$i"
      fi
    done < $ISSUES >$TMP
  )
  mv $TMP $ISSUES
  generate_html >$HTML
}

interactive ()
{
  while [ "$reply" != 'q' ]; do
    reply=
    pr
    pr "Choose one of:"
    while [ "$reply" = "" ]; do
      pr "	l	list the issues"
      pr "	t	list only unresolved issues"
      pr "	y	list issues to be updated in the spec"
      pr "	a	add an issue"
      pr "	r	mark an issue as resolved"
      pr "	u	mark the spec as up-to-date w.r.t. an issue"
      pr "	g	generate HTML page with the issues"
      pr "	q	quit"
      prn "? "
      read reply
      case "$reply" in
	l) list_issues | $PAGER;;
	a) ref=; desc=; add_issue;;
	r) num=; res=; resolve_issue;;
	u) num=; update_issue;;
	g) generate_html;;
	t) list_unresolved | $PAGER ;;
	y) list_to_be_updated | $PAGER;;
	q) ;;
	*) pr "Not understood, please try again"; reply=;;
      esac
    done
  done
}  

if [ $# = 0 ]; then
  interactive
else
  case "$1" in
    -l) list_issues;;
    -a) ref=$2; shift 2; desc="$*"; add_issue;;
    -r) num=$2; shift 2; res="$*"; resolve_issue;;
    -u) num=$2; update_issue;;
    -g) generate_html;;
    -t) list_unresolved;;
    -y) list_to_be_updated;;
    -?) quick_help;;
    *) quick_help; exit 1;;
  esac
fi

