#! /bin/sh -e
# TODO: replace tzconfig with this program

. /usr/share/debconf/confmodule

while getopts gy o; do
	case $o in
	g) ASKUTC=1 ;;
	y) CHANGE=1 ;;
	*) exit 1   ;;
	esac
done

# s390 arch has no hwclock support; if there is no hwclock just diaable
# that code path in general
if [ ! -e /sbin/hwclock ]; then
	ASKUTC=""
fi

# Set up debconf.
db_capb backup
db_title "Time Zone Configuration"

# Feed current timezone in to question.
if [ -f /etc/timezone ]; then
	db_subst tzconfig/change_timezone timezone `cat /etc/timezone`
elif [ -L /etc/localtime ]; then
	db_subst tzconfig/change_timezone timezone \
		$(readlink /etc/localtime | sed 's%^/usr/share/zoneinfo/%%')	
fi

# Let's use a state machine to let the user jump back to earlier questions.
STATE=1
LASTSTATE=6
while [ "$STATE" != 0 -a "$STATE" -le $LASTSTATE ]; do
	case "$STATE" in
	1)
		if [ "$ASKUTC" ]; then
			# Source rcS to get the current setting, and use that to
			# control the default.
			if [ -e /etc/default/rcS ]; then
				. /etc/default/rcS || true
			fi
			if [ "$UTC" = yes ]; then
				db_set tzconfig/gmt true
			else
				db_set tzconfig/gmt false
			fi
			# The cut removes info about drift from the hwclock output.
			db_subst tzconfig/gmt hwtime $(hwclock --show | cut -d ' ' -f 1-6)
			db_fset tzconfig/gmt seen false
			db_input medium tzconfig/gmt || true
		fi
	;;
	2)
		if [ ! "$CHANGE" ]; then
			# Show current time zone and ask if it should be changed.
			db_fset tzconfig/change_timezone seen false
			db_input medium tzconfig/change_timezone || true
		fi
	;;
	3)
		# Jump to end if the user doesn't want the time zone changed.
		db_get tzconfig/change_timezone
		if [ "$RET" = false -a ! "$CHANGE" ]; then
			STATE=$(($LASTSTATE - 1))
		else
			# Show top level divisions (mainly by continent).
			db_fset tzconfig/geographic_area seen false
			db_input high tzconfig/geographic_area || true
		fi
	;;
	4)
		# Prompt with a list of zones in the selected area.
		# Suckily, we have to map some of the values that were
		# prompted with to the directory names themselves.
		db_get tzconfig/geographic_area
		DIR="$RET"
		case "$DIR" in
		"Atlantic Ocean")		DIR=Atlantic	;;
		"Indian Ocean")			DIR=Indian	;;
		"Pacific Ocean")		DIR=Pacific	;;
		"System V style time zones")	DIR=SystemV	;;
		"None of the above")		DIR=Etc		;;
		esac
		if [ ! -d /usr/share/zoneinfo/$DIR ]; then
			echo "$0 internal error: /usr/share/zoneinfo/$DIR does not exist" >&2
			exit 1
		fi

		# Instantiate zone selection question for area, and
		# populate with available choices.
		db_register tzconfig/select_zone tzconfig/select_zone/$DIR || true
		db_subst tzconfig/select_zone/$DIR choices \
			$(find /usr/share/zoneinfo/$DIR -type f -printf "%f, \n" | \
			  sort | xargs echo | sed 's/,$//')

		db_fset tzconfig/select_zone/$DIR seen false
		db_input high tzconfig/select_zone/$DIR || true
	;;
	5)
		db_get tzconfig/select_zone/$DIR || true
		timezone="$DIR/$RET"

		if [ "$timezone" = "/" ]; then
			# Skipped timezone selection stage.
			timezone=$(cat /etc/timezone)
		fi

		# Set time zone.
		db_get tzconfig/change_timezone
		if [ "$RET" = true -o "$CHANGE" ]; then
			echo $timezone > /etc/timezone 
			rm -f /etc/localtime && \
				ln -sf /usr/share/zoneinfo/$timezone /etc/localtime
		fi
		
		if [ "$ASKUTC" ]; then
			# Set gmt or not. Only change the file if the value
			# changed. This must only be done after the time zone
			# file is set up.
			db_get tzconfig/gmt
			if [ "$RET" = true -a "$UTC" != yes ]; then
				sed -e 's:^UTC="no":UTC="yes":' -e 's:^UTC=no:UTC=yes:' \
					/etc/default/rcS > /etc/default/rcS.new
				CHANGEUTC=1
			elif [ "$RET" = false -a "$UTC" != no ]; then
				sed -e 's:^UTC="yes":UTC="no":' -e 's:^UTC=yes:UTC=no:' \
					/etc/default/rcS > /etc/default/rcS.new
				CHANGEUTC=1
			fi
			if [ "$CHANGEUTC" ]; then
				mv -f /etc/default/rcS.new /etc/default/rcS
				/etc/init.d/hwclock.sh start >/dev/null </dev/null
			fi
		fi
		
		db_get tzconfig/change_timezone
		if [ "$RET" = true -o "$CHANGE" ]; then
			# Display a final message giving the selected zone
			# and showing the time in that zone (and UTC for
			# comparison) and asking if it looks ok.
			utdate=$(LANG=C date -u)
			tzdate=$(LANG=C date -d "$utdate")
			db_subst tzconfig/verify_choices timezone "$timezone"
			db_subst tzconfig/verify_choices tzdate "$tzdate"
			db_subst tzconfig/verify_choices utdate $utdate
			db_fset tzconfig/verify_choices seen false
			db_input low tzconfig/verify_choices || true
		fi
	;;
	6)
		# Get the result of that last question, and if it is false,
		# loop back to start.
		db_get tzconfig/change_timezone
		if [ "$RET" = true -o "$CHANGE" ]; then
			db_get tzconfig/verify_choices
			if [ "$RET" = false ]; then
				STATE=0
			fi
		fi
	;;
	esac

	if db_go; then
		STATE=$(($STATE + 1))
	else
		STATE=$(($STATE - 1))
	fi
done
