###
### config hook
###

dbc_go(){
	local db happy default_dbtype host newhost port oldhosts authmethod_user authmethod_admin do_config need_adminpw need_userpw f _preconf_list _s _t STATEiformat ifile
	. /usr/share/dbconfig-common/dpkg/common
	dbc_config $@

	db_capb backup

	# only do this on install/reconfigure
	if [ "$dbc_command" != "configure" -a "$dbc_command" != "reconfigure" ];
	then
		return 0
	fi

	##
	## register all the dbconfig-common questions
	##
	dbc_register_debconf
	
	# make sure debconf is up to date with on-disk configuration
	dbc_preseed_package_debconf

	# and start our beautiful state-machine
	STATE=1
	while true; do
	case "$STATE" in
	# state 1 - ask if they want our help at all
	1)
		db_input medium $dbc_package/dbconfig-install || true
	;;
	# state 2 - check to see if they do. 
	#         - see if this is an upgrade newly supporting dbc
	#         - multidb support step 1
	2)
		db_get $dbc_package/dbconfig-install
		if [ "$RET" != "true" ]; then
			return 0;
		fi

		##
		## start new dbc upgrade section
		##

		# if dbc_load_include is set but the file doesn't exist
		# then let's silently exit because that would imply
		# we're running before the file is from the latest
		# version of the package which has not yet been unpacked
		if [ "$dbc_load_include" ]; then
			iformat=`echo $dbc_load_include | cut -d: -f1`
			ifile=`echo $dbc_load_include | cut -d: -f2-`
		fi

		if dpkg --compare-versions "$dbc_first_version" gt "$dbc_oldversion"; then
			##
			## if they want to import settings from a previous 
			## non-dbc version, do that and mark the questions
			## skipped 
			##
			if [ "$dbc_load_include" ] && [ -f "$ifile" ]; then
				db_input high $dbc_package/import-oldsettings || true
				eval `dbconfig-load-include $dbc_load_include_args -f $iformat $ifile`
				for f in database-type $dbc_dbtype/method remote/host remote/newhost remote/port pgsql/authmethod-admin pgsql/authmethod-user $dbc_dbtype/admin-user db/app-user db/dbname; do
					db_fset $dbc_package/$f seen true || true
				done

				db_set $dbc_package/database-type $dbc_dbtype
				db_set $dbc_package/db/app-user "$dbc_dbuser"
				db_set $dbc_package/db/dbname "$dbc_dbname"
				db_set $dbc_package/remote/host "$dbc_dbserver"
				db_set $dbc_package/remote/port "$dbc_dbport"
				db_set $dbc_package/$dbc_dbtype/app-pass "$dbc_dbpass"
				db_set $dbc_package/password-confirm "$dbc_dbpass"
			fi
		fi

		##
		## start multidb section
		## 
	
		# check to see if there's a dbtype answer already in debconf
		db_get $dbc_package/database-type && dbc_prompted_dbtype="$RET"
	
		# if the dbtype is hardcoded (using config.mysql, etc), use that
		if [ "$dbc_hardcoded_dbtype" ]; then
			dbc_dbtype=$dbc_hardcoded_dbtype
		# if dbc_dbtype is set (from above or in conf), don't bother
		elif [ "$dbc_dbtype" ]; then
			true
		# else see if they've already told us what to use, use that
		elif [ "$dbc_prompted_dbtype" ]; then
			dbc_dbtype=$dbc_prompted_dbtype
		fi

		# if the package supports multiple dbtypes, help them pick one
		if [ "$dbc_dbtypes" ]; then
		# loop through all available dbtypes
			for db in $dbc_all_supported_dbtypes; do
				# check to see $db is supported
				dbc_detect_dbtype $db
				# if we're already happy, we're already done
				if [ "$happy" ]; then
					true
				# else, if it's installed and unpacked, we're happy
				elif [ "$dbc_dbtype_installed" = "yes" ]; then
					default_dbtype=$db	
					happy="yes"
				# else if it's supported and there's nothing better...
				elif [ "$dbc_dbtype_supported" = "yes" ]; then
					if [ ! "$default_dbtype" ]; then
						default_dbtype=$db	
					fi
				fi
				# otherwise, there's no default yet, which is okay
			done

			# now that we're done with that, actually do the debconf stuff

			db_subst $dbc_package/database-type database_types "$dbc_dbtypes"
			# if dbc_dbtype is already set (from conf file) then
			# use that as a default, otherwise use our best guess
			if [ "$dbc_dbtype" ]; then
				default_dbtype="$dbc_dbtype"
			fi
			db_set  $dbc_package/database-type "$default_dbtype"
			db_input high $dbc_package/database-type || true
		fi
	;;
	# state 3 - multidb support part 2, pre-seeding, get conn. method
	3)
		if [ "$dbc_dbtypes" ]; then
			db_get  $dbc_package/database-type
			dbc_prompted_dbtype="$RET"

			# now that we have a dbtype, reload common to set other defaults
			dbc_config $@
		fi

		# there's a bit more to do with client/server rdbms
		if [ "$dbc_dbtype" = "mysql" -o "$dbc_dbtype" = "pgsql" ]; then
			# if these haven't been specified, use defaults
			if [ ! "$dbc_dbadmin" ]; then 
				dbc_dbadmin="$dbc_default_admin"; 
			fi
			if [ ! "$dbc_dbuser" ]; then 
				dbc_dbuser="$dbc_default_dbuser"
			fi
			if [ ! "$dbc_dbname" ]; then 
				dbc_dbname=`echo $dbc_package | tr -d +-.`; 
			fi
		fi

		# pre-seed any already defined values into debconf as defaults
		if [ "$dbc_upgrade" ]; then
			db_set $dbc_package/dbconfig-upgrade "$dbc_upgrade"
		fi
		if [ "$dbc_remove" ]; then
			db_set $dbc_package/dbconfig-remove "$dbc_remove"
		fi      
		if [ "$dbc_dbuser" ]; then 
			db_set $dbc_package/db/app-user "$dbc_dbuser"
		fi      
		if [ "$dbc_dbpass" ]; then 
			db_set $dbc_package/$dbc_dbtype/app-pass "$dbc_dbpass"
			db_fset $dbc_package/$dbc_dbtype/app-pass seen true
			db_set $dbc_package/app-password-confirm "$dbc_dbpass"
			db_fset $dbc_package/app-password-confirm seen true
		fi      
		if [ "$dbc_dbname" ]; then 
			db_set $dbc_package/db/dbname "$dbc_dbname"
		fi      
		if [ "$dbc_dbserver" ]; then
			db_set $dbc_package/remote/host "$dbc_dbserver"
		fi
		if [ "$dbc_dbport" ]; then
			db_set $dbc_package/remote/port "$dbc_dbport"
		fi
		if [ "$dbc_dbadmin" ]; then
			db_set $dbc_package/$dbc_dbtype/admin-user "$dbc_dbadmin"
		fi
		if [ "$dbc_ssl" = "true" -a "$dbc_dbtype" = "pgsql" ]; then
			db_set $dbc_package/pgsql/method "tcp/ip + ssl"
		fi
		db_input low $dbc_package/$dbc_dbtype/method || true
	;;
	# state 4 - do stuff based on the connection method
	4)
		db_get $dbc_package/$dbc_dbtype/method && dbc_method="$RET"

		# if package/method == tcp/ip or tcp/ip + ssl
		if [ "$dbc_method" != "unix socket" ]; then
			# look at the hosts used in any other dbconfig-using
			# package, and create a list of hosts.
			_preconf_list=` (
			for f in /etc/dbconfig-common/*.conf; do
				eval \`dbconfig-generate-include --dbserver=_s $f | grep -v '^#'\`
				[ "$_s" ] && echo $_s
			done
			) | sort | uniq`
			# turn the list into a comma separated list if it exists
			# and then substitute it into the list of available hosts
			if [ "$_preconf_list" ]; then
				_preconf_list=`echo $_preconf_list | sed -e 's/ /, /g'`
				_preconf_list="new host, $_preconf_list"
				db_subst $dbc_package/remote/host hosts "$_preconf_list"
				# and then ask them for one
				db_input high $dbc_package/remote/host || true
			fi
		# but if it is unix socket, forget all the host stuff
		else
			db_reset $dbc_package/remote/host || true
			db_reset $dbc_package/remote/newhost || true
			db_reset $dbc_package/remote/port || true
		fi
	;;
	# state 5 - get host / port info if necessary
	5)
		if [ "$dbc_method" != "unix socket" ]; then
			if [ "$_preconf_list" ]; then
				db_get $dbc_package/remote/host 
				host=$RET
			fi

			# if they've chosen "new host" or the host list was empty
			if [ ! "$host" -o "$host" = "new host" ]; then
				# prompt them for a new hostname
				db_input high $dbc_package/remote/newhost || true
			fi
		fi
	;;
	# state 6 - do stuff based on host/port selection
	6)
		if [ "$dbc_method" != "unix socket" ]; then
			if [ ! "$host" -o "$host" = "new host" ]; then
				db_get $dbc_package/remote/newhost 
				newhost="$RET"

				# add the new host to the existing list of hosts
				db_metaget $dbc_package/remote/host choices
				oldhosts="$RET"
				db_subst $dbc_package/remote/host hosts "$oldhosts, $newhost"
				db_set $dbc_package/remote/host "$newhost"
				db_fset $dbc_package/remote/host seen true
			else
				# set the "newhost" to the selected host, because
				# the second time through the configure script we'll
				# need this set
				db_set $dbc_package/remote/newhost "$host"
			fi

			# on what port?
			db_input low $dbc_package/remote/port || true
		fi
	;;
	# state 7 - pgsql specific auth stuff, part 1
	7)
		if [ "$dbc_dbtype" = "pgsql" ]; then
			# postgresql provides multiple auth types, and ssl
			# get the admin auth method
			db_input low $dbc_package/pgsql/authmethod-admin || true
		fi
	;;
	# state 8 - pgsql auth stuff, part 2
	8)
		if [ "$dbc_dbtype" = "pgsql" ]; then
			db_get $dbc_package/pgsql/authmethod-admin
			authmethod_admin="$RET"
			# default the user auth method to the admin method
			# ...but only if they haven't set one already
			if [ ! "$dbc_authmethod_user" ]; then
				db_set $dbc_package/pgsql/authmethod-user "$authmethod_admin"
			fi
			db_input low $dbc_package/pgsql/authmethod-user || true
		fi
	;;
	# state 9 - pgsql auth part 3, admin/app user, dbname
	9)
		if [ "$dbc_dbtype" = "pgsql" ]; then
			db_get $dbc_package/pgsql/authmethod-user
			authmethod_user="$RET"

			# if we are using ident, we don't need passwords
			if [ "$authmethod_admin" = "ident" ]; then
				need_adminpw="false"
			fi

			if [ "$authmethod_user" = "ident" ]; then
				need_userpw="false"
			fi
		fi

		# who's the admin user (is there any reason to even ask this?)
		# TODO: should there be a difference between the local and remote admin?
		db_input low $dbc_package/$dbc_dbtype/admin-user || true

		if [ "$need_adminpw" != "false" ]; then
			dbc_get_admin_pass
		fi

		db_input low $dbc_package/db/app-user || true

		if [ "$need_userpw" != "false" ]; then
			dbc_get_app_pass
		fi

		# get the name of the database to use
		db_input low $dbc_package/db/dbname || true
	;;
	# * - end state
	*)
		break
	;;
	esac
		if db_go; then
			STATE=$(($STATE + 1))
		else
			STATE=$(($STATE - 1))
		fi

		if [ $STATE -lt 1 ]; then
			exit 10
		fi
	done
}
