#!/bin/zsh               
use scwrypts/environment-files
#####################################################################

MAIN() {
	while [[ $# -gt 0 ]]
	do
		case $1 in
			--no-prompt ) SLIENT=1; shift 1 ;;

			* ) WARNING "argument '$1' not recognized"
				shift 1 ;;
		esac
	done

	local TEMPLATE_FILE
	[ ! $SLIENT ] && {
		yN 'change the template(s) before sync?' && {
			EDIT $(
				for TEMPLATE_FILE in $(SCWRYPTS__GET_ENV_TEMPLATE_FILES)
				do
					[ -f "$TEMPLATE_FILE" ] && echo "$TEMPLATE_FILE"
					[ -f "$TEMPLATE_FILE.descriptions" ] && echo "$TEMPLATE_FILE.descriptions"
				done
			)
		}

		for TEMPLATE_FILE in $(SCWRYPTS__GET_ENV_TEMPLATE_FILES)
		do
			{
			echo '#!/bin/zsh'
			cat "$TEMPLATE_FILE" \
				| sed '
					/__[a-z_]\+=$/d;
					/^#/d; /^$/d;
					s/^[A-Z]/export &/; s/^[^#=]\\+$/&=/;
					' \
				| LC_COLLATE=C sort -u
			} > "$TEMPLATE_FILE.temp"
			mv "$TEMPLATE_FILE.temp" "$TEMPLATE_FILE"
		done
	}

	local ENVIRONMENTS ENVIRONMENT_FILES
	local FILE NAME ENVIRONMENT_FILE

	GROUP_PIDS=()
	for GROUP in ${SCWRYPTS_GROUPS}
	do
		{
		ENVIRONMENTS=($(SCWRYPTS__GET_ENV_NAMES | sort -r))
		ENVIRONMENT_FILES=($(
			for NAME in ${ENVIRONMENTS[@]}
			do
				SCWRYPTS__GET_ENV_FILE $NAME $GROUP
			done
		))

		STATUS 'generating working environment files...'
		for FILE in ${ENVIRONMENT_FILES[@]}
		do
			GENERATE_TEMP_ENVIRONMENT_FILE "$FILE"
		done

		STATUS 'cascading environment values to children...'
		for NAME in ${ENVIRONMENTS[@]}
		do
			CASCADE_ENVIRONMENT $NAME
		done

		STATUS 'cleaning up working space...'
		for FILE in ${ENVIRONMENT_FILES[@]}
		do
			CLEANUP_ENVIRONMENT_FILE "$FILE"
		done
		SUCCESS 'finished sync!'
		} &
		GROUP_PIDS+=$!
	done
	for P in ${GROUP_PIDS[@]}; do wait $P; done
}

#####################################################################

CASCADE_ENVIRONMENT() {
	local PARENT_NAME="$1"
	local PARENT_FILE="$(SCWRYPTS__GET_ENV_FILE $PARENT_NAME $GROUP).temp"

	local CHILD_NAMES=($(echo $ENVIRONMENTS | sed 's/ \+/\n/g' |grep "^$PARENT_NAME\\."))
	[[ ${#CHILD_NAMES[@]} -eq 0 ]] && return 0

	local PARENT_VARIABLES="$(READ_PARENT_VARIABLES "$PARENT_NAME" "$PARENT_FILE")"
	[ ! $PARENT_VARIABLES ] && return 0

	local CHILD_NAME CHILD_FILE CONTENT
	for CHILD_NAME in ${CHILD_NAMES[@]}
	do
		STATUS "propagating environment '$PARENT_NAME' to child '$CHILD_NAME'"
		CHILD_FILE="$(SCWRYPTS__GET_ENV_FILE $CHILD_NAME $GROUP).temp"
		CONTENT=$(cat "$CHILD_FILE")
		echo "$PARENT_VARIABLES" | ADD_LINES
		echo "$CONTENT" > "$CHILD_FILE"
	done

	SUCCESS "finished '$PARENT_NAME' propagation"
}

#####################################################################

GENERATE_TEMP_ENVIRONMENT_FILE() {
	local FILE="$1"
	local CONTENT=$(GENERATE_TEMPLATE)

	READ_POPULATED_VARIABLES "$FILE" | ADD_LINES

	echo "$CONTENT" > "$FILE.temp"
}

ADD_LINES() {
	local LINE VARIABLE SHORT VALUE
	while read LINE
	do
		VARIABLE=$(echo $LINE | sed 's/=.*$//')
		echo $CONTENT | grep -qi "^$VARIABLE" || {
			echo $LINE | grep -q '__[a-z_]\+=' || {
				WARNING "skipping variable $(echo $LINE | sed 's/^export //; s/=.*//')
					(must be included in a template before it can be added)"
				continue
			}
			SHORT=$(echo "$VARIABLE" | sed 's/__[a-z].*//')
			CONTENT=$(echo "$CONTENT" | sed "/^$SHORT/a $LINE")
		}

		CONTENT=$(echo "$CONTENT" | sed "s%^$VARIABLE.*$%$LINE%")
	done
}

READ_POPULATED_VARIABLES() {
	local FILE="$1"
	cat "$FILE" \
		| grep -v '^#' \
		| grep -v '=$' \
		| grep -v '^$' \
		| grep -v ' # from ' \
		| awk '/^[^=]+$/{printf "%s_____",$0;next}7' \
		| sed 's/\(_____\)\(export\)/\1\n\2/; s/\(_____\)$/\1\n/' \
		| sed 's/^.*_____.*$/_____&/' \
		| sed 's/^_____export/export/' \
		| sed -z 's/[\n
] *_____/_____/g' \
		| grep -v '^$' \
		;
}

READ_PARENT_VARIABLES() {
	local PARENT_NAME="$1"
	local PARENT_FILE="$2"
	READ_POPULATED_VARIABLES "$PARENT_FILE" \
		| sed 's/_____/ /g; s/\s\+/ /g' \
		| sed 's/( /(/; s/ )/)/' \
		| sed "s/$/ # from $PARENT_NAME/" \
		| grep -v '__[a-z_]\+=' \
		;
}

CLEANUP_ENVIRONMENT_FILE() {
	cat "$1.temp" \
		| sed 's/_____$//g; s/_____/\n/g' \
		> "$1"
	
	rm "$1.temp"
}

#####################################################################
MAIN $@
