#!/bin/sh
#
# Check group file and qa scripts for a specific pcp command ($1)
#
# $1 is assumed to be _both_ the name of a command that appears in
# the QA scripts (or part of a command, e.g. purify in _setup_purify)
# and the name of a group in the group file
#
# Note: if $1 is of the form pcp-xxx, this is special, and is the name
#	of a command, but the groups are pcp and xxx
# Note: there are some special group aliases, like folio, logutil,
#	pmclient where $1 is a group name, but expands to multiple
#	commands
#

tmp=/var/tmp/check-group-$$
trap "rm -f $tmp.*; exit 0" 0 1 2 3 15
debug=true
debug=false

if [ $# -ne 1 ]
then
    echo "Usage: $0 <pcpapp>"
    exit 1
fi

touch $tmp.tmp
for seq in [0-9][0-9][0-9] [0-9][0-9][0-9][0-9]
do
    if grep -q "^$seq[: 	]" group
    then
	:
    else
	echo "$seq: Error: file exists but missing from group"
    fi
    # special control lines
    # check-group-include: group ..
    # check-group-exclude: group ..
    grp="$1"
    case "$1"
    in
	pmlogdump|pmdumplog)
	    grp="pmlogdump|pmdumplog"
	    ;;
	*)
	    grp="$1"
	    ;;
    esac
    grep '# check-group-' $seq >$tmp.chk
    if [ -s $tmp.chk ]
    then
	if grep -E "check-group-include:.* ($grp)( |\$)" <$tmp.chk >/dev/null
	then
	    $debug && echo "$seq: explicit include"
	    echo $seq >>$tmp.tmp
	    continue
	fi
	if grep -E "check-group-exclude:.* $1( |\$)" <$tmp.chk >/dev/null
	then
	    $debug && echo "$seq: explicit exclude"
	    continue
	fi
    fi

    report_group=""
    group_list=""
    # need to handle some alias cases ...
    #
    case "$1"
    in

	folio)		# executable might be pmafm or mkaf
	    ( grep -v '^[ 	]*#' $seq \
	      | grep -E -q "(^[ 	]*(pmafm|mkaf)([ '\"]|$))|([ /'\"\`_=](pmafm|mkaf)([ '\"\`_]|$))" \
	    ) && echo $seq >>$tmp.tmp
	    report_group="pmafm or mkaf"
	    ;;

	logutil)	# pmlogger_ scripts
	    ( grep -v '^[ 	]*#' $seq \
	      | grep -E -q "(^[ 	]*(pmlogger_check|pmlogger_daily|pmlogger_daily_report|pmlogger_merge|pmlogger_rewrite)([ '\"]|$))|([ /'\"\`_=](pmlogger_check|pmlogger_daily|pmlogger_daily_report|pmlogger_merge|pmlogger_rewrite)([ '\"\`_]|$))" \
	    ) && echo $seq >>$tmp.tmp
	    report_group="pmlogger_* scripts"
	    ;;

	pmclient)	# executable might be pmlient_fg
	    ( grep -v '^[ 	]*#' $seq \
	      | grep -E -q "(^[ 	]*(pmclient|pmclient_fg)([ '\"]|$))|([ /'\"\`_=](pmclient|pmclient_fg)([ '\"\`_]|$))" \
	    ) && echo $seq >>$tmp.tmp
	    report_group="pmclient et al"
	    ;;

	pmdumplog|pmlogdump)
			# these are aliases ...
			# executable might be hidden in _exercise_compression
			# wrapper from common.compress
	    ( grep -v '^[ 	]*#' $seq \
	      | grep -E -q "(^[ 	]*(pmlogdump|pmdumplog|_exercise_compression)([ '\"]|$))|([ /'\"\`_=](pmlogdump|pmdumplog|_exercise_compression)([ '\"\`_]|$))" \
	    ) && echo $seq >>$tmp.tmp
	    ;;

	pmie)		# executable might be hidden in src/grind
	    ( grep -v '^[ 	]*#' $seq \
	      | grep -E -q "(^[ 	]*(pmie|src/grind-tools)([ '\"]|$))|([ /'\"\`_=](pmie|src/grind-tools)([ '\"\`_]|$))" \
	    ) && echo $seq >>$tmp.tmp
	    ;;

	pmlogrewrite)	# executable might be hidden in mk.logfarm
	    ( grep -v '^[ 	]*#' $seq \
	      | grep -E -q "(^[ 	]*(pmlogrewrite|mk.logfarm)([ '\"]|$))|([ /'\"\`_=](pmlogrewrite|mk.logfarm)([ '\"\`_]|$))" \
	    ) && echo $seq >>$tmp.tmp
	    ;;

	pmpost)		# executable might be in $PCP_BINADM_DIR
	    ( grep -v '^[ 	]*#' $seq \
	      | grep -E "(^[ 	]*pmpost([ '\"]|$))|([ '\"\`/]pmpost([ '\"\`]|$))" >$tmp.debug \
	    ) && echo $seq >>$tmp.tmp
	    ;;

	valgrind)	# executable maybe hidden in wrappers, so look for
			# cmd and guard and wrapper, but NOT if the script
			# contains the "dual" guard ...
			# if [ "$1" = "--valgrind" ]
			#
	    if ( grep -v '^[ 	]*#' $seq \
	      | grep -E -q "(^[ 	]*(valgrind|_check_valgrind)([ '\"]|$))|([ /'\"\`_=](valgrind|_run_valgrind)([ '\"\`_]|$))" \
	    )
	    then
		if grep -q 'if \[ "$1" = "--valgrind" ]' <$seq
		then
		    # valgrind is _really_ run from the dual of this one
		    #
		    :
		else
		    echo $seq >>$tmp.tmp
		fi
	    fi
	    ;;

	pcp-*)		# pcp-xxx is cmd, expected group is pcp AND xxx
			# pcp ... xxx is also cmd
	    subcmd=`echo "$1" | sed -e 's/pcp-//'`
	    ( grep -v '^[ 	]*#' $seq \
	      | grep -E "(^[ 	]*$1([ '\"]|$))|([ '\"\`]$1([ '\"\`]|$))|(^[ 	]*pcp .*$subcmd([ '\"]|$))|([ '\"\`]$pcp .*$subcmd([ '\"\`]|$))" >$tmp.debug \
	    ) && echo $seq >>$tmp.tmp
	    group_list="`echo $1 | sed -e 's/-/ /'`"
	    ;;

	iostat)		# executable maybe pcp-iostat or pcp iostat or pmiostat
	    ( grep -v '^[ 	]*#' $seq \
	      | grep -E -q "(^[ 	]*(pcp-iostat|pcp iostat|pmiostat)([ '\"]|$))|([ /'\"\`_=](pcp-iostat|pcp iostat|pmiostat)([ '\"\`_]|$))" \
	    ) && echo $seq >>$tmp.tmp
	    ;;

	not_in_ci)
	    ( grep '^[ 	]*#.*:not_in_ci:' $seq >$tmp.debug  \
	    )  && echo $seq >>$tmp.tmp
	    ;;

	pmlogcompress)	# this is a group
	    ( grep -v '^[ 	]*#' $seq \
	      | grep -E -q "(^[ 	]*(pmlogcompress|pmlogdecompress)([ '\"]|$))|([ /'\"\`_=](pmlogcompress|pmlogdecompress)([ '\"\`_]|$))" \
	    ) && echo $seq >>$tmp.tmp
	    ;;

	pmlogmv)	# this is a group or maybe hidden in mk.logfarm
	    ( grep -v '^[ 	]*#' $seq \
	      | grep -E -q "(^[ 	]*(pmlogmv|pmlogcp|mk.logfarm)([ '\"]|$))|([ /'\"\`_=](pmlogmv|pmlogcp|mk.logfarm)([ '\"\`_]|$))" \
	    ) && echo $seq >>$tmp.tmp
	    ;;

	*)
	    ( grep -v '^[ 	]*#' $seq \
	      | grep -E "(^[ 	]*$1([ '\"]|$))|([ /'\"\`]$1([ '\"\`]|$))" >$tmp.debug \
	    ) && echo $seq >>$tmp.tmp
	    $debug && [ -s $tmp.debug ] && echo $seq: && cat $tmp.debug
	    ;;
    esac
done

sed <group -e '/^$/d' -e '/^[^0-9]/d' -e 's/ .*//' -e 's/:/ /' \
| while read seq state
do
    [ -f "$seq" ] && continue
    [ "$state" = reserved ] && continue
    [ "$state" = retired ] && continue
    echo "$seq: Error: in group but file not found"
done

sort -o $tmp.scripts $tmp.tmp

if [ -z "$group_list" ]
then
    # $1 IS the group name
    #
    check -r -n -g "$1" \
    | sort \
    | while read f
    do
	[ -f "$f" ] && echo "$f"
    done >$tmp.group
else
    # Need to match ALL the groups in the group file ... these ones are OK
    #
    for grp in $group_list
    do
	check -r -n -g "$grp" \
	| while read f
	do
	    [ -f "$f" ] && echo "$f"
	done
    done >$tmp.tmp
    xpect="`echo $group_list | wc -w | sed -e 's/ //g'`"
    sort $tmp.tmp \
    | uniq -c \
    | while read num seq
    do
	[ "$num" = "$xpect" ] && echo $seq
    done >$tmp.group
fi

[ -z "$report_group" ] && report_group="$1"

comm -23 $tmp.scripts $tmp.group >$tmp.tmp
if [ -s $tmp.tmp ]
then
    echo "$report_group in QA scripts and NOT in group ..."
    sort -n $tmp.tmp | sed -e 's/^/    /'
    echo
fi

comm -13 $tmp.scripts $tmp.group >$tmp.tmp
if [ -s $tmp.tmp ]
then
    echo "$report_group in group and NOT in QA scripts ..."
    sort -n $tmp.tmp | sed -e 's/^/    /'
    echo
fi

comm -12 $tmp.scripts $tmp.group >$tmp.tmp
echo "$report_group in group and QA scripts `wc -l <$tmp.tmp | sed -e 's/ //g'` times"

if $debug
then
    for suff in scripts group
    do
	echo "Saving tmp.$suff ..."
	mv $tmp.$suff tmp.$suff
    done
fi
