#!/bin/sh
#
# Make a new PCP QA test that runs an existing test under valgrind
#
# Copyright (c) 1997-2002 Silicon Graphics, Inc.  All Rights Reserved.
# Copyright (c) 2021 Ken McDonell.  All Rights Reserved.
#
# Usage: new-grind [-n|-v] seq-no
#

# generic initialization
. ./common.rc

min=1600
max=1999
max_probes=200

_usage()
{
    echo >&2 "Usage: new-grind [options] old-seqno [new-seqno]"
    echo >&2
    echo >&2 "Options:"
    echo >&2 "-n   show-me, change nothing"
    echo >&2 "-v   verbose"

    exit 1
}

showme=false
verbose=false
while getopts 'nrsv?' p
do
    case "$p"
    in
	n)	showme=true
		;;
	v)	verbose=true
		;;
	?)	echo "bad arg: $p"; _usage
		# NOTREACHED
    esac
done
shift `expr $OPTIND - 1`

if [ $# -ne 1 -a $# -ne 2 ]
then
    _usage
    # NOTREACHED
fi

if [ ! -f group ]
then
    echo "Error: no \"group\" file"
    exit 1
fi

oldseq=$1
if [ ! -f "$oldseq" ]
then
    echo "Error: test \"$oldseq\" does not exist"
    exit 1
fi

if [ $# -eq 2 ]
then
    newseq=$2
    if [ -f "$newseq" ]
    then
	echo "Error: test \"$newseq\" already exists"
	exit 1
    fi
    if grep -E "^($newseq )|($newseq:retired )" group
    then
	echo "Error: test \"$newseq\" already defined in \"group\" file"
	exit 1
    fi
else
    newseq=''
fi

if grep "^do_valgrind=false" $oldseq >/dev/null
then
    :
else
    echo "Error: test \"$oldseq\" does NOT look like it was created recently with ./new"
    echo "... no \"do_valgrind=false\" line"
    exit 1
fi

if grep -E "_run_(valgrind|helgrind) " $oldseq >/dev/null
then
    if grep "_run_valgrind \.\.\.your test goes here\.\.\." $oldseq >/dev/null
    then
	echo "Error: test \"$oldseq\" still contains the dummy \"_run_valgrind\" line"
	exit 1
    fi
else
    echo "Error: test \"$oldseq\" does not contain a \"_run_valgrind\" or"
    echo "\"_run_helgrind\" line"
    exit 1
fi

oldgroup=`grep "^$oldseq[ :]" <group`
if [ -z "$oldgroup" ]
then
    echo "Error: test \"$oldseq\" not found in \"group\" file"
    exit 1
fi

if [ ! -w group ]
then
    echo "Error: cannot write index file \"group\""
    exit 1
fi

tmp=/tmp/new-grind-$$
sts=1
trap "rm -f $tmp.*; exit \$sts" 0 1 2 3 15

if [ -z "$newseq" ]
then
    try=`expr $oldseq + 1`
    try=`printf "%03d\n" $try`
    # first $oldseq+1, then keep serially probing
    #
    $verbose && echo >&2 "Info: start probing at $try"
    probe=0
    while [ $probe -lt $max_probes ]
    do
	if grep "^$try[ :]" <group >/dev/null
	then
	    # already allocated ... try again
	    #
	    seed=$try
	    try=`expr $try + 1`
	    try=`printf "%03d\n" $try`
	    $verbose && echo >&2 "Info: try $try"
	else
	    newseq=$try
	    break
	fi
    done

    if [ $probe -eq $max_probes ]
    then
	echo >&2 "Error: after $max_probes attempts, no unassigned tests in the range $oldseq ...  Time to increase \$max_probes"
	exit 1
    fi

    if [ -f $newseq ]
    then
	echo >&2 "Error: test $newseq already exists, but not in group file!"
	exit
    fi
fi

if $showme
then
    echo $newseq
    exit
fi

echo "New test number $newseq"
newgroup=`echo $oldgroup | sed -e "s/^$oldseq\([: ]\)/$newseq\1/" -e 's/$/ valgrind/'`

if grep 'non-valgrind' $oldseq >/dev/null
then
    : annotation already added
else
    $PCP_AWK_PROG <$oldseq >$oldseq.new-grind '
BEGIN			{ done = 0 }
NF == 1 && $1 == "#" && done == 0	{
			  print "#"
			  print "# non-valgrind variant, see qa/'$newseq' for the valgrind variant"
			  done = 1
			}
			{ print }
/^  *do_valgrind=true/	{ print "elif which valgrind >/dev/null 2>&1"
			  print "then"
			  print "    [ \"$PCPQA_VALGRIND\" = both ] || \\"
			  print "        _notrun \"valgrind variant qa/'$newseq' will be run\""
			  next
			}'
    mv $oldseq.new-grind $oldseq
    chmod 755 $oldseq
fi

groups=`echo "$oldgroup" | sed -e "s/^$oldseq[: ]//" -e 's/ local//'`

$PCP_AWK_PROG <$oldseq >$newseq '
BEGIN			{ done = 0 }
NF == 0			{ exit }
/non-valgrind variant/	{ print "# valgrind variant, see qa/'$oldseq' for the non-valgrind variant"
			  print "#"
			  print "# check-group-include: '"$groups"'"
			  done = 1
			  next
			}
/PCP QA Test No/	{ sub(/'$oldseq'$/, "'$newseq'") }
			{ print }'
			
cat <<End-of-File >>$newseq

seq=\`basename \$0\`
echo "QA output created by \$seq"

# get standard environment, filters and checks
. ./common.product
. ./common.filter
. ./common.check

_check_valgrind

_cleanup()
{
    cd \$here
    \$sudo rm -rf \$tmp \$tmp.*
}

status=0	# success is the default!
\$sudo rm -rf \$tmp \$tmp.* \$seq.full
trap "_cleanup; exit \\\$status" 0 1 2 3 15

# real QA test starts here
export seq
./$oldseq --valgrind

# success, all done
exit
End-of-File
chmod 755 $newseq

echo "Creating $newseq script"
echo "Adding $newseq to group index"

# sort the tests numerically
#
sed <group \
    -e "/^$newseq:reserved/d" \
| $PCP_AWK_PROG '
BEGIN				{ state = "head" }
state == "head" && /^[0-9]/	{ state = "list" }
				{ print >"'$tmp'." state }'
echo "$newgroup" >>$tmp.list
sort -n $tmp.list >>$tmp.head
cp $tmp.head group

# make a $newseq.out placeholder if not already done
#
if [ ! -f $newseq.out ]
then
    echo "Creating output $newseq.out"
    echo "QA output created by $newseq" >$newseq.out
    if [ -f $oldseq.out ]
    then
	sed -e '1s/$/ --valgrind/' <$oldseq.out >>$newseq.out
    else
	echo "[skeleton from qa/new, replace me]" >>$newseq.out
    fi
fi

# and finally, don't forget the git work ...
#
git add $newseq $newseq.out

sts=0
exit
