#!/bin/sh

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

XORGCONFIG_MAIN="/etc/X11/xorg.conf"
XORGCONFIG_TEMPLATE="/usr/share/alterator-x11/xorg.conf"
XORGCONFIG_WORKCOPY="/var/cache/alterator/xorg.conf"

XORGDRV_DIR="$(getconf LIBDIR)/X11/modules/drivers"
XTEST_ANSWER="/var/cache/alterator/xtest-answer"

XCONFTOOL="/usr/bin/xconf"
SETUPDRVTOOL="/usr/bin/x11setupdrv"

###helper functions
out_option()
{
    [ -n "$2" ] && printf '%s "%s"' "$1" "$2"
}


to_plist()
{
	while read field value; do
		printf ' %s "%s" ' "$field" "$value"
	done
}

#read autodetect information
read_autodetect_data()
{
	echo -n '('
	#video data
	video_scan|to_plist
	#monitor data
	out_option "monitor" "$(monitor_scan)"
	echo ')'
}

xorg_config_name()
{
	if [ -f "$XORGCONFIG_WORKCOPY" ] ;then
		echo "$XORGCONFIG_WORKCOPY"
	else
		echo "$XORGCONFIG_MAIN"
	fi
}

made_workcopy()
{
	if [ -f "$XORGCONFIG_MAIN" ] ;then
		cp "$XORGCONFIG_MAIN" "$XORGCONFIG_WORKCOPY"
	else
		cp "$XORGCONFIG_TEMPLATE" "$XORGCONFIG_WORKCOPY"
	fi
}

sure_workcopy()
{
	[ -f "$XORGCONFIG_WORKCOPY" ]  || made_workcopy
}


clear_workcopy()
{
	[ -f "$XORGCONFIG_WORKCOPY" ] && rm -f "$XORGCONFIG_WORKCOPY"
}

clear_answer()
{
	[ -f "$XTEST_ANSWER" ] && rm -f "$XTEST_ANSWER"
}

is_ok_answer()
{
	[ -f "$XTEST_ANSWER" ] && grep -qs '^ok$' "$XTEST_ANSWER"
}

clear_ddc()
{
    /usr/libexec/alterator-x11/ddcclean
}

#### exit handler

exit_handler()
{
	echo "exit_handler..." >&2
	trap - TERM HUP EXIT

	[ -f "$XORGCONFIG_MAIN" ] && "$SETUPDRVTOOL"
	clear_workcopy
	clear_answer
	clear_ddc
}



trap exit_handler TERM HUP EXIT

#### initialize static data

x11presetdrv #sure we use right nvidia.xinf files
clear_workcopy #remove workcopy
clear_answer #remove xtest answer file
clear_ddc #remove ddc cache
autodetect_data="$(read_autodetect_data)" #detect video hardware

echo "backend ready..." >&2

on_message()
{
	local IFS="$IFS"
	case "$in_action" in
		list) 
			IFS='	'
			if [ "$in__objects" = "cards" ];then
				echo '('
				ls "$XORGDRV_DIR"/*_drv.so|
					sed -r 's,.*/([a-z0-9]+)_drv\.so$,\1,'|
				video_drivers|
					while read driver description rest; do
						echo '('
						printf '"%s"' "$driver"
						printf ' xdrivername "%s"' "$description"
						echo ')'
					done
				echo ')'
			elif [ "$in__objects" = "monitors" ];then
				echo '('
				monitor_drivers|
				    cut -f1 -d';'|
				    sort -u|
				    sed 's,.*,("&"),'
				echo ')'
			elif [ "${in__objects#monitors/}" != "$in__objects" ]; then
				local vendor="${in__objects#monitors/}"
				echo '('
				monitor_drivers|
				    grep "^$vendor;"|
				    cut -f2 -d';'|
				    sed -r 's,^[[:space:]]*(.*),("\1"),'
				echo ')'
			else
				echo '()'
			fi
			;;
		read)
			IFS='	'
			if [ "$in__objects" = "autodetect" ];then
				echo "$autodetect_data"
			elif [ "$in__objects" = "monitor" ];then
				printf '(vendor "%s")' "$(monitor_drivers | egrep "[^;]+;[[:space:]]*$in_name;"|cut -f1 -d';')"
			elif [ "$in__objects" = "xdriver" ];then
				printf '(xdepth "%s")' "$(echo "$in_name"|video_drivers|cut -f3)"
			else
				local config="$(xorg_config_name)"
				echo '('
				if [ -f "$config" ]; then
				    #video
				    $XCONFTOOL -g "$config"|
					video_drivers|
					(read driver description rest;
					 printf 'xdriver "%s" xdrivername "%s"' "$driver" "$description")

				    out_option "monitor" "$($XCONFTOOL -n "$config"| cut -f1 -d'|')"
				    out_option "xdepth" "$($XCONFTOOL -c "$config")"
				    out_option "xresolution" "$($XCONFTOOL -r "$config")"
				fi
				echo ')'
			fi
			;;
		write)
			if [ "$in__objects" == "/" ]; then
    			    sure_workcopy
			    local config="$(xorg_config_name)"
			    [ -n "$in_xdriver" ] && video_setup "$in_xdriver" "$config"
			    [ -n "$in_monitor" ] && monitor_setup "$in_monitor" "$config"
			    [ -n "$in_xdepth" ] && $XCONFTOOL -C "$in_xdepth" "$config" "$config"
			    [ -n "$in_xresolution" ] && $XCONFTOOL -R "$in_xresolution" "$config" "$config"
			    echo '()'
			elif [ "$in__objects" = "commit" ] ;then
				[ -f "$XORGCONFIG_WORKCOPY" ] && mv -f "$XORGCONFIG_WORKCOPY" "$XORGCONFIG_MAIN"
				echo '()'
			elif [ "$in__objects" = "test" ] ;then
			    "$SETUPDRVTOOL" "$XORGCONFIG_WORKCOPY" #setup right symlinks
			    [ -f "$XORGCONFIG_WORKCOPY" ] && XAUTHORITY=  /usr/bin/xinit /usr/bin/xtest -- :9 -config "$XORGCONFIG_WORKCOPY"
    			    if is_ok_answer ;then
				echo '()'
			    else
				echo '(error "X11 test failed")'
			    fi
			else
			    echo '()'
			fi
			;;
			
		*)
			echo '#f'
			;;
	esac
}

message_loop
