#!/bin/bash

# I originally intended this to work with bourne shells, but then I
# discovered that Solaris' /bin/sh -still- doesn't understand shell
# functions.  Grrr...  So because RHEL 3, Solaris 7, IRIX 6.5.x and
# Tru64 4.x all have /bin/ksh, I'm switching to that.

#set -x

# this is definitely not the most efficient language choice for this
# project, but:
# 1) All of our autoinstall systems have /bin/sh present during an
#    install
# 2) We're not using any external programs during the main loop, so it
#    may not actually be all -that- slow anyway

# Deter/prevent an extra degree of whitespace munging
IFS=""
export IFS

function usage
{
	(
	echo
	echo "$0: usage follows"
	echo "   -p pattern  specify the shell pattern, before or after which the text will be added"
	echo "   -a          perform operation after the pattern"
	echo "   -b          perform operation before the pattern"
	echo "   -i          perform an insert"
	echo "   -r          perform a removal (not yet implemented)"
	echo "   -t text     the text to add"
	echo "   -f          add text only before/after the -first- occurrence of the pattern"
	echo "   -F filename file to operate on.  Default is to read from stdin and write to stdout"
	echo "   -d          output some debugging information"
	echo
	echo "You must always specify both -p and -t"
	echo "You must always specify either -a or -b but not both"
	echo "You must always specify either -i or -r but not both"
	) 1>&2
	exit 1
}

function premature_eof
{
	echo "$0: Warning: EOF detected prior to pattern, stream unchanged" 1>&2
}

# getopt seems to make a general mess of quoting, so we do our own
# options parsing...
#set -- `getopt p:abirt: $@`

#if [ $? != 0 ]
#then
#   usage
#fi

pattern=""
after=""
text=""
insert=""
remove=""
first="false"
debug="false"
filename=""

while [ "$#" -ge 1 ]
do
	: '$1' is $1, '$2' is $2
	case "$1" in
		-p)
			if [ "$pattern" != "" ]
			then
				echo -p must be specified exactly once
				usage
			fi
			pattern="$2"
			shift
			shift
			;;
		-F)
			if [ "$filename" != "" ]
			then
				echo -F must be zero or one times, not more
				usage
			fi
			filename="$2"
			shift
			shift
			;;
		-f)
			if [ "$first" != "false" ]
			then
				echo -f may only be specified once 1>&2
				usage
			fi
			first=true
			shift
			;;
		-d)
			if [ "$debug" != "false" ]
			then
				echo -d may only be specified once 1>&2
				usage
			fi
			debug=true
			shift
			;;
		-a)
			if [ "$after" != "" ]
			then
				echo -a and -b are mutually exclusiva 1>&2
				usage
			fi
			after=true
			shift
			;;
		-b)
			if [ "$after" != "" ]
			then
				echo -a and -b are mutually exclusiva 1>&2
				usage
			fi
			after=false
			shift
			;;
		-t)
			if [ "$text" != "" ]
			then
				echo -t must be specified exactly once
				usage
			fi
			text="$2"
			shift
			shift
			;;
		-i)
			if [ "$insert" != "" ]
			then
				echo -i may only be specified once 1>&2
				usage
			fi
			if [ "$remove" != "" ]
			then
				echo -i and -r are mutually exclusive 1>&2
				usage
			fi
			insert="true"
			shift
			;;
		-r)
			if [ "$remove" != "" ]
			then
				echo -r may only be specified once 1>&2
				usage
			fi
			if [ "$insert" != "" ]
			then
				echo -i and -r are mutually exclusive 1>&2
				usage
			fi
			remove="true"
			shift
			;;
		*)
			usage
			;;
	esac
done

if [ "$pattern" = "" ]
then
	echo -p must be specified exactly once 1>&2
	usage
fi

if [ "$text" = "" ]
then
	echo -t must be specified exactly once 1>&2
	usage
fi

if [ "$insert" = "" ] && [ "$remove" = "" ]
then
	echo You must specify one of -i or -r 1>&2
	usage
fi

if [ "$after" = "" ]
then
	echo You must specify one of -a or -b 1>&2
	usage
fi

if [ "$filename" = "" ]
then
	: 'nothing to do'
else
	# create a temporary file, with who-cares-what-permissions
	cp "$filename" "$filename.temp"
	# our output will go back into the original file, with the same
	# permissions as before, by virtue of the >
	exec > "$filename"
	# we'll read datfa from the temporary file
	exec < "$filename.temp"
fi

if [ "$insert" = true ]
then
	# insert case
	found=false
	if [ "$after" = true ]
	then
		# this is the simpler of the two insert cases.  In this one, we add "$text"
		# after the pattern occurrence(s)
		while :
		do
			if read line
			then
				case "$line" in
					$pattern)
						found=true
						echo "$line"
						echo "$text"
						if [ "$first" = true ]
						then
							[ "$debug" = true ] && echo Setting cattoend
							cattoend=true
							break
						fi
						;;
					*)
						echo "$line"
						;;
				esac
			else
				: 'we are at EOF, so we do not need to cattoend'
				break
			fi
			if [ "$cattoend" = true ]
			then
				break
			fi
		done
	else
		# this is the more complicated of the two insert cases.  In this one, we add "$text"
		# before the pattern occurrence(s)
		if read prevline
		then
			:
		else
			# if we did not even get one line, then just give the premature EOF warning and exit
			premature_eof
			exit 0
		fi
		while :
		do
			if read line
			then
				eof=false
			else
				eof=true
			fi
			case "$prevline" in
				$pattern)
					found=true
					echo "$text"
					echo "$prevline"
					if [ "$eof" = true ]
					then
						break
					else
						if [ "$first" = true ]
						then
							echo "$line"
							[ "$debug" = true ] && echo Setting cattoend
							cattoend=true
							break
						fi
					fi
					;;
				*)
					echo "$prevline"
					;;
			esac
			if [ "$cattoend" = true ]
			then
				break
			fi
			if [ "$eof" = true ]
			then
				break
			fi
			prevline="$line"
		done
	fi
fi

[ "$debug" = true ] && echo '$found' is "$found"
if [ "$found" = false ]
then
	premature_eof
fi

if [ "$remove" = true ]
then
	echo 'Sorry, remove is not implemented yet :)' 1>&2
	exit 0
fi

[ "$debug" = true ] && echo At end, and cattoend is "$cattoend"
if [ "$cattoend" = true ]
then
	while read line
	do
		echo "$line"
	done
fi

# clean up the temporary file, if needed
if [ "$filename" = "" ]
then
	: 'nothing to do'
else
	rm "$filename.temp"
fi