#!/bin/bash
# Copyright (C) 2010 - 2019 FARGOS Development, LLC
# $Id$
# Append/Remove/Prepend elements to a path
# pathedit {-a|-r|-p} [-s separator] [-os outputSeparator] initialPath arg [...]
# PORTABILITY NOTE: this uses arrays to preserve the structure of each
# command line token.
# Since bash was chosen as the implementation target, native arithmetic
# expressions are used.

declare -a outputElements # this will be an array

mode="a"
inputSeparator=":"
outputSeparator=""

while test $# -gt 0
do
	case "${1}" in
	-h | -help | --help)
		printf "usage: %s [{-a|-r|-p}] [--is inputSeparator] [{-[-o]s outputSeparator} | --space] initialPath arg [...]\n" "${0}" >&2
		printf "  -a = append, -p = prepend, -r = remove, defaults to \"-${mode}\"\n" >&2
		printf "  Note: order of elements in initialPath will not be altered\n" >&2
		printf "  --is = specify input separator, defaults to \"%s\"\n" "${separator}" >&2
		printf "  --os = specify output separator, defaults to input separator\n" >&2
		printf "  --space = force output separator to be space\n" >&2
		printf "  Hint: reversal of a list can be done via -p \"\" currentPath\n" >&2
		exit 1
		;;
	-a)
		mode="a"
		;;
	-p)
		mode="p"
		;;
	-r)
		mode="r"
		;;
	-s | -os | --os)
		outputSeparator="${2}"
		shift
		;;
	-is | --is)
		inputSeparator="${2}"
		shift
		;;
	--space)
		outputSeparator=" "
		;;
	*)
		break
		;;
	esac
	shift
done

if test -z "${outputSeparator}"
then
	outputSeparator="${inputSeparator}"
fi

argCount=0
newPath=""
totalElements=0
for elem in "$@"
do
	argCount=$(( argCount + 1 ))
	if test -z "${elem}"
	then # null argument
		continue
	fi
	if test ${argCount} -eq 1
	then
		effectiveMode="a"
	else
		effectiveMode="${mode}"
	fi
#echo effectiveMode ${effectiveMode} arg ${argCount} is ${elem}
	splitPath=`echo ${elem} | sed -e "s/${inputSeparator}/ /g"`
	found=0
	for pElem in ${splitPath}
	do
		for priorElem in "${outputElements[@]}"
		do
#echo pElem=${pElem} priorElem=${priorElem}
			if test "${pElem}" = "${priorElem}"
			then
				found=1
				break
			fi
		done
#echo totalElements=${totalElements} pElem=${pElem} found=${found}
		if test "${found}" -eq 0
		then # not found
			case "${effectiveMode}" in
			a)
				outputElements[${totalElements}]="${pElem}"
				totalElements=$(( totalElements + 1 ))
				newPath="${newPath}${newPath:+${outputSeparator}}${pElem}"
				;;
			p)
				outputElements[${totalElements}]="${pElem}"
				totalElements=$((totalElements + 1 ))
				newPath="${pElem}${newPath:+${outputSeparator}}${newPath}"
				;;
			esac
		fi
	done # end for each pElem
done # end for each argument
echo ${newPath}
exit 0
