#!/bin/sh

# Shell script to convert a SCC logbook to html-format.
# Copyright (C) 2001-2004 Open Challenge B.V.
# Copyright (C) 2004-2005 OpenEyeT Professional Services.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; see the file COPYING.
# If not, write to the Free Software Foundation,
# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# Contact information: www.OpenEyeT.nl/scc/index.html 

# SCC-release:	1.6.26
# file-version:	$Revision: 1.65 $


ProgName=${0##*/};			export ProgName

if [ $# -ne 1 ]
then
	echo "Syntax error, use ${ProgName} <name>" >&2
	exit 1
fi

SCC_BIN=/opt/scc/bin
SCC_TOP=/var/opt/scc
export SCC_BIN SCC_TOP

export SCC_DATA=${SCC_TOP}/data
export SCC_TMP=${SCC_TOP}/tmp
export SCC_CONF=/etc/opt/scc/conf

export TMPDIR=${SCC_TMP}
export TMP=${SCC_TMP}

export SHELL=/bin/sh
export LANG=C

umask 077

PATH=/sbin:/usr/sbin:/usr/bin:/bin;	export PATH

# Use the following utilities for SunOS.
if [ -x /usr/ccs/bin/what ]
then
	alias what=/usr/ccs/bin/what
fi
if [ -x /usr/xpg4/bin/awk ]
then
	alias awk=/usr/xpg4/bin/awk
fi
if [ -x /usr/xpg4/bin/grep ]
then
	alias grep=/usr/xpg4/bin/grep
fi
if [ -x /usr/xpg4/bin/tr ]
then
	alias tr=/usr/xpg4/bin/tr
fi

cd ${SCC_TMP}

export TMP_FILE=${SCC_TMP}/scc_log_html_$$

trap "rm -f ${TMP_FILE}" 0
trap "exit 2" 1 2 3 15

TABLE_TAG="<TABLE SUMMARY=\"Summary of scc-runs\" BORDER CELLSPACING=1 CELLPADDING=4>"
TOP_NAME="<A NAME=cfg_top></A>"
TOP_URL="<A HREF=#cfg_top>Top</A>&nbsp;&nbsp;&nbsp;&nbsp;"

echo '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">'
echo "<HTML>"

echo "<HEAD>"
echo '<LINK HREF="style.css" REL="stylesheet" TYPE="text/css">'
echo "<TITLE>Logbook: $1</TITLE>"
echo "</HEAD>"

echo "<BODY>"
echo "${TOP_NAME}"

echo "<H1>Logbook: ${1}</H1>"

# DO NOT CHANGE THE FOLLOWING HTML-CODE WITHOUT CONSULTING scc.cgi IN scc-srv
echo "<H4>"
echo "	<A HREF=index.html>Home</A>&nbsp;&nbsp;&nbsp;&nbsp;"
echo "	<A HREF=scc.${1}.html>Configuration</A>&nbsp;&nbsp;&nbsp;&nbsp;"
echo "	<A HREF=#cfg_statistics>Statistics</A>"
echo "</H4>"
echo "<H4>Summary of runs of SCC</H4>"

# Replace special HTML-characters in input.
sed	-e 's/&/\&amp;/g'	\
	-e 's/</\&lt;/g'	\
	-e 's/>/\&gt;/g'	\
	-e 's/"/\&quot;/g' >${TMP_FILE}

# Build a table with URL's to reported differences in the logbook.
# Use the date/time of the run as the ID for HREF and NAME.
# Sort the data reverse to show the most recent change at the top of the table.
# Check the code in scc-log for the specific layout of the logbook.
grep -e ":result::" -e ":remark::" -e ":runtime::" -e ":count::" ${TMP_FILE}	|
awk -F: '/:result::/	{
				stat_cnt_runs++;
				if ( length( prev_res ) )
				{
					# restart or identical, no number of differences.
					print prev_res ":" ":" prev_runtime ":" prev_remark;
					prev_remark="";
					prev_runtime="";
				}
				prev_res=$0;
			}
	/:remark::/	{
				# A remark can contain ":", syntax of a line is: <date>:<time>:remark::<remark>
				prev_remark = $5;
				for ( i = 6; i <= NF; i++ )
				{
					prev_remark = sprintf( "%s: %s", prev_remark, $i );
				}
			}
	/:runtime::/	{
				# Use a separate counter as older versions of SCC did not record the runtime.
				stat_runtime_cnt++;
				stat_runtime_total+=$NF;
				if ( $NF > stat_runtime_max )
				{
					stat_runtime_max=$NF;
				}
				if ( $NF < stat_runtime_min || stat_runtime_min == 0 )
				{
					stat_runtime_min=$NF;
				}
				prev_runtime=$NF;
			}
	/:count::/	{
				stat_change_cnt++;
				stat_change_total+=$NF;
				if ( $NF > stat_change_max )
				{
					stat_change_max=$NF;
				}
				if ( $NF < stat_change_min || stat_change_min == 0 )
				{
					stat_change_min=$NF;
				}
				# changes detected, report
				print prev_res ":" $NF ":" prev_runtime ":" prev_remark;
				prev_res=""
				prev_remark=""
			}
END			{
				# unreported results?
				if ( length( prev_res ) )
				{
					print prev_res ":" ":" prev_runtime ":" prev_remark;
				}
				if ( stat_cnt_runs == 0 )
				{
					stat_cnt_runs=1;
					stat_runtime_cnt=1;
				}
				printf( "0:9:runs total          : %d\n", stat_cnt_runs );
				printf( "0:8:runs with changes   : %d\n", stat_change_cnt );
				printf( "0:7:runs perc. changes  : %d\n", ( 100 * stat_change_cnt ) / stat_cnt_runs );
				printf( "0:6:change count min.   : %d\n", stat_change_min );
				printf( "0:5:change count max.   : %d\n", stat_change_max );
				if ( stat_change_cnt == 0 )
				{
					stat_change_cnt = 1;
				}
				printf( "0:4:change count average: %d\n", stat_change_total / stat_change_cnt );
				printf( "0:3:runtime min.        : %d\n", stat_runtime_min );
				printf( "0:2:runtime max.        : %d\n", stat_runtime_max );
				printf( "0:1:runtime average     : %d\n", stat_runtime_total / stat_runtime_cnt );
			}'			|
sort -r						|
awk -F":" '{
		# The variable u is not initialized in a BEGIN-clause.
		# Therefore we check for the first record.
		if ( NR == 1 )
		{
			print u;
			print "<TR>";
			print "	<TH>Date</TH>";
			print "	<TH>Time</TH>";
			print "	<TH>Runtime</TH>";
			print "	<TH>Result</TH>";
			print "	<TH>Count</TH>";
			print "	<TH>Remark</TH>";
			print "</TR>";
		}
	}
/^0:/	{
		# We print the statistics as pre-formatted text.
		# Last part of the data. The END-statement takes care of the </PRE>.
		# Format of the data is:
		#0:<order>:<label>:<value>
		if ( statistics == 0 )		# No heading yet?
		{
			print "</TABLE>";
			print "<HR>";
			print "<A NAME=cfg_statistics></A>"
			printf( "<H4>%sStatistics</H4>\n", t );
			print "<PRE>";
			statistics=1;
		}
		printf( "%s: %d\n", $3, $4 );
		next;
	}
{
	# Show data of a run.
	# Format of the input is:
	#<date>:<time>:result::different:<count>:<runtime>:<remark>
	print "<TR>";

	if ( $5 == "different" )
	{
		# When there are differences, we want to go back to this point in the table
		printf( "<TD><A NAME=\"back_%s_%s\"></A>%s</TD>\n", $1, $2, $1 );	# Date
	}
	else
	{
		print "	<TD>" $1 "</TD>";	# Date
	}
	print "	<TD>" $2 "</TD>";		# Time
	if ( length( $7 ) > 0 )			# Runtime available?
	{
		printf( "	<TD align=right>%s</TD>\n", $7 );
	}
	else
	{
		print "	<TD>&nbsp;</TD>";
	}
	if ( $5 == "different" )		# Result
	{
		printf( "	<TD><A HREF=\"#%s_%s\">%s</A></TD>\n", $1, $2, $5 );
	}
	else
	{
		printf( "	<TD>%s</TD>\n", $5 );
	}
	align=" align=right";			# Only count of differences is aligned.
	if ( length( $6 ) > 0 )			# Count available?
	{
		printf( "	<TD align=right>%s</TD>\n", $6 );
	}
	else
	{
		print "	<TD>&nbsp;</TD>";
	}
	remark = $8;				# Possibly contains ":"
	for ( i = 9; i <= NF; i++ )
	{
		remark = sprintf( "%s: %s", remark, $i );
	}
	align=""
	if ( length( remark ) > 0 )
	{
		printf( "	<TD%s>%s</TD>\n", align, remark );
	}
	else
	{
		print "	<TD>&nbsp;</TD>";
	}
	print "</TR>";
}
END	{
	print "</PRE>";
}' t="${TOP_URL}" u="${TABLE_TAG}"

# Now the table is present, we show the data.
# Use the date/time of the run as the ID for HREF and NAME.
awk -F: '{
	# Sort the log file, most recent run first, 
	# within the run keep the data in the order of the log file.
	log_date=$1;
	log_time=$2;
	gsub( "-", "", log_date );
	gsub( /\./, "", log_time );
	printf( "%s:%06d:%s:%s\n", log_date, log_time, NR, $0 );
}' ${TMP_FILE}				|
sort -t: -k 1,1nr -k 2,2nr -k 3,3n	|
sed -e 's/^[0-9]*:[0-9]*:[0-9]*://'	|
awk -F":"	'/:result::different$/	{
			if ( show_data )
			{
				print "</PRE>";		# end of previously showed data
			}
			show_data=1;			# indicate that we are going to show differences
			prev_class="";			# reset class-identifier for this run
			print "<HR>";
			printf( "<H4>%s<A HREF=#back_%s_%s>Back</A>&nbsp;&nbsp;&nbsp;&nbsp;", u, $1, $2 );
			printf( "<A NAME=\"%s_%s\">Differences at: %s %s</A></H4>\n", $1, $2, $1, $2 );
			print "<PRE>";
			next;
		}
	/:result::identical$|:result::.re.start$/	{
			if ( show_data )
			{
				print "</PRE>";		# end of previously showed data
			}
			show_data=0;			# the are no differences: do not show data
			next;
		}
	/:data::/	{
			if ( show_data )
			{
				# Do not show the classification on each line, only once in bold format.
				change=$5;		# old/new
				# $6 is empty to separate changed data from the classification
				class=$7;
				for ( i = 8; length( $i ) > 0; i++ )
				{
					class=sprintf( "%s - %s", class, $i );
				}
				if ( class != prev_class )
				{
					print "<BR>";
					print "<B>" class "</B>";
					prev_class=class;
				}
				printf( "%s:	", change );
				for ( i++; i < NF; i++ )
				{
					printf( "%s:", $i );
				}
				print $i;
			}
			next;
		}
		{
			# No data, classifications:
			# possible classifications are: count, remark, previous date and time
			if ( show_data )
			{
				printf( "%-30.30s: %s\n", $3, $5 );
			}
			next;
		}
END	{
	if ( show_data )
	{
		print "</PRE>";		# end of previously showed data
	}
}' u="${TOP_URL}"

rm -f ${TMP_FILE}

echo "<P>Generated by SCC (&copy; <A HREF=http://www.OpenEyeT.nl>OpenEyeT Professional Services</A>) on $(date)</P>"

echo "</BODY>"
echo "</HTML>"

exit 0
