#!/bin/sh

APACHE_CONFDIR="/etc/httpd2/conf"
ALTERATOR_SCONF="900-alterator.conf"
VHOSTS_PATH="/var/www/vhosts"
LOG_PATH="/var/log/httpd2"

_()
{
LANG=${in_language%%;*}.utf8 gettext "alterator-apache2" "$1"
}

#turn off auto expansion
set -f

. /usr/share/alterator/build/backend3.sh

print_aes_name()
{
	local object="$1"
	local name="$2"

	case "$name" in
		available)
			printf '%s-available' "$object"
			;;
		enabled)
			printf '%s-enabled' "$object"
			;;
		start)
			printf '%s-start.d' "$object"
			;;
		*)
			printf ''
			;;
	esac
}

print_a2used_name()
{
	local object="${1%s}"
	local enabled="$2"
	local s=

	case "$enabled" in
		yes)
			s="en"
			;;
		no)
			s="dis"
			;;
	esac
	printf 'a2%s%s' "$s" "$object"
}

P_VirtualHost="[Vv][Ii][Rr][Tt][Uu][Aa][Ll][Hh][Oo][Ss][Tt]"
P_OT_VirtualHost="^[[:space:]]*<$P_VirtualHost[[:space:]]+[^[:space:]]+>[[:space:]]*(|(.*))\$"
P_ZT_VirtualHost="^[[:space:]]*\/<$P_VirtualHost>[[:space:]]*(|(.*))\$"
P_pre_VirtualHost="1,/$P_OT_VirtualHost/{b}
/$P_ZT_VirtualHost/,\${b}
"
P_post_VirtualHost="
"

P_Server="[Ss][Ee][Rr][Vv][Ee][Rr]"
P_Name="[Nn][Aa][Mm][Ee]"
P_Path="[Pp][Aa][Tt][Hh]"
P_Admin="[Aa][Dd][Mm][Ii][Nn]"
P_ServerName="$P_Server$P_Name"
P_ServerPath="$P_Server$P_Path"
P_ServerAdmin="$P_Server$P_Admin"
P_DocumentRoot="[Dd][Oo][Cc][Uu][Mm][Ee][Nn][Tt][Rr][Oo][Oo][Tt]"
P_ErrorLog="[Ee][Rr][Rr][Oo][Rr][Ll][Oo][Gg]"

for p in P_ServerName P_ServerPath P_ServerAdmin P_DocumentRoot P_ErrorLog;
do
	eval "P_f_${p#P_}=\$$p[[:space:]]"
	eval "P_fs_${p#P_}=^[[:space:]]*\$$p[[:space:]]"
done

P_Summary="^[[:space:]]*\#[[:space:]]*Summary:"
P_f_Summary="\#[[:space:]]*Summary:"
P_fs_Summary="^[[:space:]]*$P_f_Summary"
P_pre_Summary="1,/^[[:space:]]*[^[:space:]]/{
	/^[[:space:]]*[^[:space:]]/b e1
	b
}
: e1
1,/^[[:space:]]*($|[^\#])/{
	/^[[:space:]]*\#/{
		1,/$P_Summary/{
"
P_post_Summary="
		}
	}
}"

get_summary()
{
	local fn="$1"
	sed -rn "${P_pre_Summary}1,1s/$P_fs_Summary[[:space:]\'\"]*([^[:space:]\'\"].*[^[:space:]\'\"])[[:space:]\'\"]*\$/\1/p$P_post_Summary" \
		"$fn"
}

on_message()
{
	. /usr/share/alterator/build/apache2.sh
	case "$in_action" in
		constraints)
			echo '('
			case "$level" in
				0)
					printf 'name (label "%s")\n' "`_ "Group of configs"`"
					printf 'summary (label "%s")\n' "`_ "Summary"`"
					;;
				2)
					if [ ${objs[2]} = "available" ]; then
						case "${objs[1]}" in
							ports|mods|sites|extra)
								printf 'name (label "%s" required #t)\n' "`_ "Name"`"
								printf 'status_def (label "%s")\n' "`_ "By default"`"
								printf 'enabled (label "%s")\n' "`_ "Enabling"`"
								printf 'summary (label "%s")\n' "`_ "Summary"`"
								;;
						esac
					fi
					;;
				3)
					if [ ${objs[2]} = "available" ]; then
						case "${objs[1]}" in
							sites)
								printf 'summary (label "%s")\n' "`_ "Summary"`"
								printf 'ServerName (label "%s")\n' "ServerName"
								printf 'ServerPath (label "%s")\n' "ServerPath"
								printf 'ServerAdmin (label "%s")\n' "ServerAdmin"
								printf 'DocumentRoot (label "%s")\n' "DocumentRoot"
								printf 'ErrorLog (label "%s")\n' "ErrorLog"
								;;
						esac
					fi
					;;
			esac
			echo ')'
			;;
		list)
			echo '('
			if [  $level = 0 ]; then
				printf '("ports" summary "%s")\n' \
						"`_ "Configuring IP addresses and ports, which hears server"`"
				printf '("mods" summary "%s")\n' \
						"`_ "Manage load modules"`"
				printf '("sites" summary "%s")\n' \
						"`_ "Manage sites"`"
				printf '("extra" summary "%s")\n' \
						"`_ "Advanced settings"`"
			else
				case "${objs[1]}" in
					ports|mods|sites|extra)
						if [ $level = 1 ]; then
							printf '("available" name "%s" summary "%s")\n' \
									`print_aes_name "$object1" "available"` \
									"`_ "Available configs"`"
							printf '("enabled" name "%s" summary "%s")\n' \
									`print_aes_name "$object1" "enabled"` \
									"`_ "Enabled configs"`"
							printf '("start" name "%s" summary "%s")\n' \
									`print_aes_name "$object1" "start"` \
									"`_ "Manage automation integration configs"`"
						else
							case "${objs[2]}" in
								available)
									local conf_suf="conf"
									if [ "${objs[1]}" = "mods" ]; then
										conf_suf="load"
									fi
									if [ $level = 2 ]; then
										local epath="$APACHE_CONFDIR"/`print_aes_name "${objs[1]}" "enabled"`
										find "$epath" -maxdepth 1 -name "*.$conf_suf" -type f -o -type l -exec readlink -e {} \; | \
											{
												local nefnames=0
												local efnames=""
												local fname
												while read -r fname; do
													let nefnames++
													efnames[$nefnames]="$fname"
												done
												/usr/sbin/a2chkconfig_list "${objs[1]}" | \
													{
														local ns=0
														local sns=""
														local sus=""
														local sn
														local su
														local t
														while read -r t sn su; do
															let ns++
															sns[$ns]="$sn"
															sus[$ns]="$su"
														done
														local apath="$APACHE_CONFDIR"/`print_aes_name "${objs[1]}" "available"`
														find "$apath" -maxdepth 1 -name "*.$conf_suf" -type f -o -type l | \
															{
																local fn
																while read -r fn; do
																	local i
																	local en="`_ "no"`"
																	local fname=`readlink -e "$fn"`
																	for i in `seq 1 "$nefnames"`; do
																		if [ "x$fname" = "x${efnames[$i]}" ]; then
																			en="`_ "yes"`"
																			break;
																		fi
																	done
																	local name=`echo "$fn"|sed -e "s@^$apath/\([^[:space:]]\+\)\.$conf_suf\\$@\1@"`
																	local status_def="`_ "none"`"
																	for i in `seq 1 "$ns"`; do
																		if [ "x$name" = "x${sns[$i]}" ]; then
																			status_def="${sus[$i]}"
																			break;
																		fi
																	done
																	case "$status_def" in
																		yes)
																			status_def="`_ "enable"`"
																			;;
																		no)
																			status_def="`_ "disable"`"
																			;;
																	esac
																	local summary="`get_summary "$fn"`"
																	printf '("%s" enabled "%s" status_def "%s" summary "%s")\n' \
																			"$name" "$en" "$status_def" "$summary"
																done
															}
													}
											}
									elif [ $level = 3 ]; then
										if [ "${objs[3]}" = "avail_actions" ]; then
											printf '("nop" label "-- %s --")\n' "`_ "select action"`"
											printf '("none_def" label "%s")\n' "`_ "default none"`"
											printf '("en_def" label "%s")\n' "`_ "enable by default"`"
											printf '("dis_def" label "%s")\n' "`_ "disable by default"`"
											printf '("enable" label "%s")\n' "`_ "enable"`"
											printf '("disable" label "%s")\n' "`_ "disable"`"
											printf '("delete" label "%s")\n' "`_ "delete"`"
										fi
									fi
									;;
							esac
						fi
						;;
				esac
			fi
			echo ')'
			;;
		read)
			echo '('
			if [  $level = 3 ]; then
				case "${objs[1]}" in
					sites)
						case "${objs[2]}" in
							available)
								printf 'group_name "%s"\n' "${objs[1]}/${objs[3]}"
								printf 'group_summary "%s %s"\n' \
										"`_ "Configure virtual host"`" "${objs[3]}"
								local fname="$APACHE_CONFDIR/`print_aes_name "${objs[1]}" "available"`/${objs[3]}.conf"
								printf 'summary "%s"\n' "`get_summary "$fname"`"
								sed -rn "$P_pre_VirtualHost
/$P_fs_ServerName/{
	1,1s/$P_fs_ServerName[[:space:]\'\"]*([A-Za-z0-9.:\/-]+).*\$/ServerName \"\1\"/p}
/$P_fs_ServerPath/{
	1,1s/$P_fs_ServerPath[[:space:]\'\"]*([^[:space:]'\"]+).*\$/ServerPath \"\1\"/p}
/$P_fs_ServerAdmin/{
	1,1s/$P_fs_ServerAdmin[[:space:]\'\"]*([^[:space:]'\"]+).*\$/ServerAdmin \"\1\"/p}
/$P_fs_DocumentRoot/{
	1,1s/$P_fs_DocumentRoot[[:space:]\'\"]([^[:space:]'\"]+).*\$/DocumentRoot \"\1\"/p}
/$P_fs_ErrorLog/{
	1,1s/$P_fs_ErrorLog[[:space:]\'\"]*([^[:space:]'\"]+).*\$/ErrorLog \"\1\"/p}
$P_post_VirtualHost" \
									"$fname"
								;;
						esac
						;;
				esac
			elif [  $level != 0 ]; then
				printf 'group_name "%s"\n' "${objs[1]}"
				case "${objs[1]}" in
					ports)
						printf 'group_summary "%s"\n' \
							"`_ "Configuring IP addresses and ports, which hears server"`"
						;;
					mods)
						printf 'group_summary "%s"\n' \
							"`_ "Manage load modules"`"
						;;
					sites)
						printf 'group_summary "%s"\n' \
							"`_ "Manage sites"`"
						;;
					extra)
						printf 'group_summary "%s"\n' \
							"`_ "Advanced settings"`"
						;;
				esac
			fi
			echo ')'
			;;
		write)
			if [  $level = 3 ]; then
				case "${objs[1]}" in
					sites)
						case "${objs[2]}" in
							available)
								local fname="$APACHE_CONFDIR/`print_aes_name "${objs[1]}" "available"`/${objs[3]}.conf"
								local summary="`get_summary "$fname"`"
								local fo_summary
								if [ "x$summary" != "x" ]; then
									fo_summary="y"
								fi
								sed -rn "$P_pre_VirtualHost
/$P_fs_ServerName/{
	1,1s/$P_fs_ServerName[[:space:]\'\"]*([A-Za-z0-9.:\/-]+).*\$/ServerName=\"\1\"/p}
/$P_fs_ServerPath/{
	1,1s/$P_fs_ServerPath[[:space:]\'\"]*([^[:space:]'\"]+).*\$/ServerPath=\"\1\"/p}
/$P_fs_ServerAdmin/{
	1,1s/$P_fs_ServerAdmin[[:space:]\'\"]*([^[:space:]'\"]+).*\$/ServerAdmin=\"\1\"/p}
/$P_fs_DocumentRoot/{
	1,1s/$P_fs_DocumentRoot[[:space:]\'\"]([^[:space:]'\"]+).*\$/DocumentRoot=\"\1\"/p}
/$P_fs_ErrorLog/{
	1,1s/$P_fs_ErrorLog[[:space:]\'\"]*([^[:space:]'\"]+).*\$/ErrorLog=\"\1\"/p}
$P_post_VirtualHost" \
									"$fname" | \
									{
										local ServerName fo_ServerName
										local ServerPath fo_ServerPath
										local ServerAdmin fo_ServerAdmin
										local DocumentRoot fo_DocumentRoot
										local ErrorLog fo_ErrorLog

										local o

										while read -r o; do
											eval "$o"
											eval "fo_${o%=*}=y"
										done
										for o in summary ServerName ServerPath ServerAdmin DocumentRoot ErrorLog; do
											local no
											local oold
											local foold
											local onew
											local p_o
											local p_f_o
											local p_fs_o
											local sa
											local p_pre p_post

											eval "oold=\"\$$o\""
											eval "foold=\"\$fo_$o\""
											eval "onew=\"\$in_$o\""
											if [ "x$o" = "xsummary" ]; then
												no="# Summary:"
												p_o="$P_Summary"
												p_f_o="$P_f_Summary"
												p_fs_o="$P_fs_Summary"
												p_pre="$P_pre_Summary"
												p_post="$P_post_Summary"
											else
												no="$o"
												eval "p_o=\"\$P_$o\""
												eval "p_f_o=\"\$P_f_$o\""
												eval "p_fs_o=\"\$P_fs_$o\""
												p_pre="$P_pre_VirtualHost/$p_fs_o/{
"
												p_post="
}$P_post_VirtualHost"
											fi

											if [ "x$onew" = "x" ]; then
												sa="1,1d"
											elif [ "x$oold" = "x$onew" ]; then
												continue
											else
												local eonew="`echo "$onew"|sed -e 's@\\\\@\\\\\\\\@g;s@/@\\\\/@g'`"
												if [ "x$o" != "xsummary" ]; then
													eonew="`echo "$eonew"|sed -r "s/^[[:space:]'\\"]*([^[:space:]'\\"].*[^[:space:]'\\"])[[:space:]'\\"]*$/\\1/"`"
												fi
												if [ "x$foold" = "xy" ]; then
													sa="	1,1s/^([[:space:]]*)$p_f_o.*\$/\1$no $eonew/"
												elif [ "x$o" = "xsummary" ]; then
													p_pre="1,1{
"
													p_post="
}"
													sa="	i\\$no $eonew"
												else
													p_pre="1,/$P_ZT_VirtualHost/{
"
													p_post="
}"
													sa="	\$i\\	$no $eonew"
												fi
											fi
											sed -i -r "$p_pre$sa$p_post" "$fname"
										done
									}
								;;
						esac
						;;
				esac
			fi
			echo '()'
			;;
		new)
			if [  $level = 2 ]; then
				case "${objs[1]}" in
					sites)
						case "${objs[2]}" in
							available)
								local vhpath="$VHOSTS_PATH/$in_name"
								mkdir -p "$vhpath/html"
								chgrp webmaster "$vhpath" "$vhpath/html"
								chmod 2775 "$vhpath" "$vhpath/html"
								local fname="$APACHE_CONFDIR/`print_aes_name "${objs[1]}" "available"`/$in_name.conf"
								echo "# Summary: Name-based Virtual Hosts, generated alterator-apache2

<VirtualHost *>
	ServerAdmin \"webmaster@$in_name\"
	ServerName \"$in_name\"
	DocumentRoot \"$vhpath/html\"
	ErrorLog \"$LOG_PATH/$in_name.error_log\"
</VirtualHost>" > "$fname"
								;;
						esac
						;;
				esac
			fi
			echo '()'
			;;
		nop)
			echo '()'
			;;
		none_def|en_def|dis_def|delete)
			if [ $level = 3 ]; then
				case "${objs[1]}" in
					ports|mods|sites|extra)
						if [ "${objs[2]}" = "available" ]; then
							if [ "$in_action" = "delete" ] &&
									[ "${objs[1]}" != "mods" ]; then
								local fname="$APACHE_CONFDIR/`print_aes_name "${objs[1]}" "available"`/${objs[3]}.conf"
								rm -f "$fname"
							else
								local conf="$APACHE_CONFDIR/`print_aes_name "${objs[1]}" "start"`/$ALTERATOR_SCONF"
								local p_yes="[Yy][Ee][Ss]"
								local p_no="[Nn][Oo]"
								local p_yn="\($p_yes\)\|\($p_no\)"
								local p_f="^[[:space:]]*${objs[3]}=\|\([[:space:]]\+\)"
								local p_e="\(\([[:space:]].*\)\|\)$"
								local p1="$p_f$p_yn$p_e"
								if [ "$in_action" = "none_def" ]; then
									sed -i -e "/$p1/d" "$conf" 2>&1 >/dev/null || :
								else
									local action="yes"
									local p="$p_n"
									if [ "$in_action" = "dis_def" ]; then
										action="no"
										p="$p_y"
									fi
									sed -i -e "/$p_f$p$p_e/s/^.*$/${objs[3]}=$action/" "$conf" 2>&1 >/dev/null || :
									grep -q -s "$p1" "$conf" || \
										{
											printf '%s=%s\n' "${objs[3]}" "$action" >> "$conf"
										}
								fi
							fi
							/usr/sbin/a2chkconfig 2>&1 >/dev/null || :
						fi
						;;
				esac
			fi
			echo '()'
			;;
		enable|disable)
			if [ $level = 3 ]; then
				case "${objs[1]}" in
					ports|mods|sites|extra)
						case "${objs[2]}" in
							available)
								local action="yes"
								if [ "$in_action" = "disable" ]; then
									action="no"
								fi
								/usr/sbin/`print_a2used_name "${objs[1]}" "$action"` "${objs[3]}" 2>&1 >/dev/null ||:
								;;
						esac
						;;
				esac
			fi
			echo '()'
			;;
		*)
			echo '#f'
			;;
	esac
}

message_loop
