#!/bin/sh
# -[Fri Mar  4 17:01:36 2005 by cxh]-
# Color the coverage file with the appropriate accepted ratings


############################################################################
# ptII/adm/gen-latest/makefile runs this script, for example:
# sh /home/bldmastr/ptII/adm/bin/coveragerating /home/bldmastr/ptII \
#	/home/www/cvswww/ptolemy/nightly/coverage.html

# To test, edit this file and set testing=yes
# Get the original coverage source file:
#   scp gigasource:/home/www/cvswww/ptolemy/nightly/coverage.html.bak coverage.orig
# Copy the coverage.orig file each time and run the script
#   cp coverage.orig coverage.html; ~/ptII/adm/bin/coveragerating /vol/maury/maury2/cxh/ptII /tmp/coverage.html


testing=no
# Uncomment next line if testing
#testing=yes

############################################################################
progname=`basename $0`
if [ $# -ne 2 ]; then
	echo "$0: Usage: $progname ptIItreedirectory summaryhtmlfile"
	exit 3
fi

tree=$1
summaryfile=$2
#tree=/users/ptII/adm/dists/ptII1.0devel 
#summaryfile=/users/ptdesign/public_html/java/js/coverage.html

javafiles=/tmp/coveragerating.javafiles

ratingfile=/tmp/coveragerating.ratingfile

complexityfile=/tmp/coveragerating.complexity

#find /tmp -name "$ratingfile" -mtime +1 -exec rm {} \;

# Create a file that has three records on each line:
#  1. The filename    
#  2. The AcceptedRating
#  3. The ProposedRating

if [ "$testing" = "no" ]; then 
    rm -f $ratingfile
fi

if [ ! -f $ratingfile ]; then
	echo "Regenerating $javafiles"
	find $tree -xdev \( -name adm -o -name "*.tmp" \) -prune -o -name '*.java' -print > $javafiles

	echo "Regenerating $ratingfile"
	cat $javafiles | xargs egrep '@AcceptedRating|@ProposedRating|@Pt.AcceptedRating|@Pt.ProposedRating' | 
	        # Remove leading spaces
	        sed 's/^ *//' |
		awk '$0 ~/ProposedRating/ {
					     # The rating is the word after
					     # the @ProposedRating tag
					     proposedRating = ""
					     for (i=1; i<=NF; i++) {
						if ( $i ~ /ProposedRating/) {
						    proposedRating = $(i+1)
						    proposedRatingFile=$1
						}
					     }

					  }
		     $0 ~/AcceptedRating/ {  split($1,f,":");
					     for (i=1; i<=NF; i++) {
						if ( $i ~ /AcceptedRating/) {
						    acceptedRating = $(i+1)
						}
					     }
					     if ( proposedRatingFile != $1) {
						# Error, file did not contain
						# a proposed rating
					        #proposedRating = acceptedRating
					     }

					     print f[1], acceptedRating, proposedRating
					  }' |
		# Remove the leading part of the tree name
                # Convert / to .
                # Remove the leading .					  
		sed -e "s=$tree==" \
			-e 's=/=.=g' \
			-e 's=^\.==g' \
			> $ratingfile
fi

# Create a file that has three fields on each line:
# 1) The string "complexity"
# 2) The file name
# 3) The cyclometric complexity

if [ "$testing" = "no" ]; then 
    rm -f $complexityfile
fi

if [ ! -f $complexityfile ]; then
	echo "Regenerating $complexityfile"
	complexityfile_tmp=/tmp/coveragerating.complexity_tmp
        if [ "$testing" = "no" ]; then 
	    rm -f $complexityfile_tmp
	fi	
	if [ ! -f $complexityfile_tmp ]; then

	    for javafile in `cat $javafiles`
	    do
		jv-scan --complexity $javafile >> $complexityfile_tmp
	    done    
        fi	    
	# Look for all the lines with two fields, add a complexity tag
	# Remove the leading part of the tree name
        # Convert / to .
        # Remove the leading .					  
	# Sort by complexity
	awk ' NF == 2 {print "complexity", $0}' < $complexityfile_tmp |
	    sed -e "s@$tree/@\.@" \
		-e 's@/@.@g' \
		-e 's=^complexity \.=complexity =g' |
	    sort +2n -3n > $complexityfile

	#rm -f $complexityfile_tmp
fi


# Read in the rating file, then the coverage file
awk '{
     if ($0 !~ /</) {
	if (NF == 3 && $1 ~ "complexity") {
	    # Reading in the complexity file
	    # It should be first in the list of files read in because
	    # we keep track of the rank
	    print "complexity: " $2, $3
	    complexityValue = $3 
	    complexityRank[$2] = NR

	    complexity[$2] = $3
	    maxComplexityRank = NR
	} else {
	    # Reading in the rating file, which has no < chars
	    print $1,$2
	    color = $2
	    
	    # If the color is yellow, then substitute in gold
	    if (color ~ /ellow/) {
		color = "#ffaa00"
	    }
	    rating[$1] = color

	    color = $3

	    # If the color is yellow, then substitute in gold
	    if (color ~ /ellow/) {
		color = "#ffaa00"
	    }
	    proposedRating[$1] = color
	}
     } else {
	# Reading in the coverage html file
	if ($0 ~ />Package /) {
	    split($3,p,"<")
	    # Remove the leading .
	    package=substr(p[1], 2, length(p[1])) 
	    #printf("%s %s <a name=%c%s%c>%s</a></th></TR>\n", $1, $2, 34, package, 34, package)

	    # Convert the dot separate package name to a / separated name
	    packageAsDirectory=""
	    npkg = split(package, pkg, ".") 
	    for ( i=1; i<=npkg; i++) {
		packageAsDirectory = packageAsDirectory "/" pkg[i]
	    }

	    printf("%s %s <a name=%c%s%c>%s</a>\n", $1, $2, 34, package, 34, package)
	    printf(" (<a href=%chttp://chess.eecs.berkeley.edu/ptolemy/reviews%s/%c>Reviews</a>,\n",34, packageAsDirectory, 34)

	    printf(" <a href=%chttp://chess.eecs.berkeley.edu/ptolemy/src/ptII/doc/codeDoc%s/package-summary.html%c>JavaDoc</a>,\n ", 34, packageAsDirectory, 34)

	    printf(" <a href=%cdoccheck%s/PackageErrors.html%c>Doccheck</a>)</th></TR>\n", 34, packageAsDirectory, 34)
	} else {
	    if ( $0 ~ /<TR><th align="center">/) {
		if ($0 !~ /TOTAL/) {
		    nf=split($2,f,"<")
		    nff=split(f[1],ff,">")	
		    file=package "." ff[2]
		    
		    # Reassemble the slashes in the filename
		    nfilearray=split(file,filearray,".")
		    filename=filearray[1]
		    for(i=2;i<nfilearray;i++) {
			filename = filename "/" filearray[i]
		    }

		    #print "-------------"file, rating[file], filename
		    printf("%s ",$1)

		    printf("%s>",ff[1]);
		    
		    # If the rating does not match the proposed rating,
		    # we italicize the filename
		    if (rating[file] != proposedRating[file]) {
			needsReviewOpen="<i>"
			needsReviewClose="</i>"
		    } else {
			needsReviewOpen=""
			needsReviewClose=""
		    }  
		    # 34 is double quote
		    printf("<a href=%c%s.html%c>%s<font color=%s>%s</font>%s</a></th>", 34, filename, 34, needsReviewOpen, rating[file], ff[nff], needsReviewClose);

		    #for(i=3;i<nnf;i++) {
		    #	printf("%s>",ff[i]);
		    #}

		    #printf("%s",ff[nnf]);

		    # Print the complexity value
		    complexityValue = complexity[file]
		    if (complexityValue == "") {
			complexityValue = "&nbsp;"
 		    }
		    if (maxComplexityRank != 0) {
			percentComplexityRank = int(complexityRank[file]/maxComplexityRank * 100.0)
		    } else {
			percentComplexityRank = 0
		    }
	    if (complexityValue > 500) {
		complexityValue="<font color=#ff0000>" complexityValue"</font>"
	    }

		    # If the file is in the top 95%, we print it in red
		    if (percentComplexityRank >= 95) {
			printf("<td><font color=#ff0000>%s %2d%%</font></td>", complexityValue, percentComplexityRank) 
		    } else {
			printf("<td>%s %2d%% </td>", complexityValue, percentComplexityRank) 
		    }

		    printf("<");
		    for(i=3;i<nf;i++) {
			printf("%s<",f[i])
		    }
		    printf("%s ",f[nf]);

		    for(i=3;i<NF;i++) {
			printf("%s ",$i)
		    }
		    printf("%s\n",$NF);

		} else {
		    print $0
		}
	    } else {
		print $0
	    }
	}
    }
}' $complexityfile $ratingfile $summaryfile |
sed 's@<th align="center">method</th>@<th align="center"><a href="#complexity">complexity</a></th><th align="center">method</th>@' |
sed 's@<TR><th align="center">TOTAL</th>@<TR><th align="center">TOTAL</th><td>\&nbsp;</td>@' |
awk '{
	if (sawheader==1) {
	    print $0
	} else {
	    if ($0 ~ /<H1> Package Coverage <\/H1>/) {
		sawheader=1
	    } 
	}
     }
     END {
	print "<h2><a name=\"definitions\">Definitions</a></h3>" 
	print "<h3><a name=\"complexity\">Complexity</a></h3>" 
	print "The complexity column measures the cyclomatic complexity"
	print "<br>The first number is the cyclomatic complexity as reported"
	print "by the GNU jv-scan program.  In general, low numbers are"
	print "good, high numbers are not so good"
	print "<a href=\"http://www.sei.cmu.edu/str/descriptions/cyclomatic.html\">SEI</a>"
	print "defines cyclomatic complexity:"
	print "<BLOCKQUOTE>"
	print "... it measures the number of linearly-independent paths"
	print "through a program module. This measure provides a single"
	print "ordinal number that can be compared to the complexity of"
	print "other programs."
	print "</BLOCKQUOTE>"
	print "<br>The second number is the rank of the file as a percentage"
	print "of all the files."
	print "Files that are in the top 95% are colored red.  These files"
	print "are the most complex files in the tree, and therefore the most"
 	print "likely to have complex bugs.  These files should probably"
	print "be refactored to aid in testability"
	print "<br>If a file has only a percentage, then jv-scan failed"
	print "to process it."
	print "<h3><a name=\"doccheck\">Doccheck</a></h3>" 
	print "Doccheck is a javadoc doclet that checks for javadoc bugs."
	print "See "
	print "<a href=\"http://java.sun.com/developer/earlyAccess/doccheck/\"><code>http://java.sun.com/developer/earlyAccess/doccheck/</code></a>"
	print "<p>You may also find the "
	print "<a href=\"doccheck/\">Doccheck Main Page</a> of interest"
     }' > /tmp/coveragerating.out

# Create a TOC
awk ' BEGIN {
	print "<html><head>"
	print "<title> @tree@ Coverage Summary</title>"
	print "</head><body>"
	print "<h1>&nbsp;&nbsp;Package Coverage</h1>"
	print "&nbsp;&nbsp;File names in <i>italic</i> are files that are ready for"
	print "<href=\"http://chess.eecs.berkeley.edu/ptolemy/reviews/index.htm\" target=\"_top\">review</a>"
	print "because the <code>@AcceptedRating</code> and the"
	print "<code>@ProposedRating</code> are different."
	print "<p>&nbsp;&nbsp;Other definitions/explanations can be found"
	print "<a href=\#definitions\">below</a>."
	print "<menu>"
    }
    { if (printedDate == 0) {
        printedDate = 1
	print date
      }
      if ($0 ~ />Package /) {
	split($4,p,"\"")
	package=p[2]
	printf("<li> <a href=%c#%s%c>%s</a>\n", 34, package, 34, package)
      }
    }
    END {
        print "</menu>" 
    }' date="`date`" /tmp/coveragerating.out |
sed "s=@tree@=$tree=" > /tmp/coveragerating.toc

cp $summaryfile $summaryfile.bak
cat /tmp/coveragerating.toc /tmp/coveragerating.out > $summaryfile

#rm -f /tmp/coveragerating.toc /tmp/coveragerating.out
