###
### config hook
###

dbc_go(){
	local f db happy default_dbtype host newhost port oldhosts authmethod_admin do_config _preconf_list _s _t STATE iformat ifile install_question migrating userdb_prio supported_dbtypes
	. /usr/share/dbconfig-common/dpkg/common
	_dbc_debug "(config) dbc_go() $@"

	dbc_config $@

	db_capb backup

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

	##
	## register all the dbconfig-common questions
	##
	## note that this can fail in the case that dbconfig-common is being
	## installed at the same time as the dependant package and the latter
	## is preconfigured before we are (no way to avoid this without being
	## in base).  in this case we gracefully exit and defer to the second
	## time the config script is run by dpkg in the postinst.   note if that
	## "hack" in dpkg ever goes away we can still work around the issue so
	## i think it's fair to avoid over-complicating things in the dependency
	## chain.
	##
	if ! dbc_register_debconf; then
		_dbc_debug "dbconfig-common not yet setup, deferring configuration."
		return 0
	fi
	
	# make sure debconf is up to date with on-disk configuration
	dbc_read_package_config
	dbc_preseed_package_debconf

	# Find out whether the database has been purged on a previous occasion. If
	# so, we'll have to give the user a chance to re-install it.
	db_get $dbc_package/purge
	if [ "$RET" = true ]; then
		dbc_command=reconfigure
	fi

    # check out if they're migrating from a non-dbc version
    if [ "$dbc_oldversion" ] && [ "$dbc_first_version" ] && \
        dpkg --compare-versions "$dbc_first_version" gt "$dbc_oldversion"; then
		migrating="yes"
	fi

	# if this is a frontend app, then the user/db type questions get
	# a raised priority
	userdb_prio="low"
	if [ "$dbc_frontend" ]; then
		userdb_prio="medium"
		need_adminpw="false"
	else
		userdb_prio="low"
	fi

	# and if they're upgrading from any previous version, we *may*
	# not need to ask for an admin password.  we can't tell at this
	# point because the upgrade files are likely not unpacked at
	# this point, so we will instead ask later in the postinst.
	if [ "$dbc_oldversion" ] && [ "$dbc_command" != "reconfigure" ]; then
		need_adminpw="false"
	fi

	# the first question we ask will differ depending on how we're invoked
	if [ "$migrating" ]; then
		install_question="$dbc_package/dbconfig-upgrade"
	elif [ "$dbc_command" = "configure" ]; then
		install_question="$dbc_package/dbconfig-install"
	else
		install_question="$dbc_package/dbconfig-reinstall"
		# if we are reconfiguring (via dpkg-reconfigure), also leave a hint
		# for our future postinst selves so we know we *should* run the code
		# that would otherwise think we were upgrading
		db_set $dbc_package/internal/reconfiguring true
	fi

	##
	## start new dbc upgrade section
	##
	# if there is a previously existing version already installed
	# *and* the maintainer has provided the first version that used
	# dbconfig-common *and*  this version is newer than the
	# previously installed version... do the dbc import stuff.
	if [ "$migrating" ]; then
		dbc_migrate
	fi

	# and start our beautiful state-machine
	# we start in STATE=1 (install_question) in all but one situation:
	#   - we're installing a frontend/readonly app
	if [ ! "$dbc_frontend" ]; then
		STATE=1
	else
		STATE=2
	fi
	while true; do
	case "$STATE" in
	# state 1 - ask if they want our help at all
	1)
		db_input high $install_question || 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 $install_question
		if [ "$RET" != "true" ]; then
			db_set $dbc_package/internal/skip-preseed true
			return 0;
		fi
		db_set $dbc_package/dbconfig-install true

		##
		## start multidb section
		## 
		# if the dbtype is hardcoded (using config.mysql, etc), use that
		if [ "$dbc_hardcoded_dbtype" ]; then
			dbc_dbtype=$dbc_hardcoded_dbtype
		# else if the package supports multiple dbtypes, help them pick one
		elif [ "$dbc_dbtypes" ]; then
		# loop through the listed dbtypes, fall back to all those available
			supported_dbtypes=$(echo $dbc_dbtypes | sed 's/,/ /g')
			for db in $supported_dbtypes $dbc_all_supported_dbtypes; do
				# if we're already happy, we're already done
				if [ "$happy" ]; then
					true
				# else, if it's supported, installed and unpacked, we're happy
				elif dbc_detect_supported_dbtype $db; then
					# if it's installed, we're happy
					if dbc_detect_installed_dbtype $db; then
						happy="yes"
					fi
					# but in any case it's be the default even if not happy
					default_dbtype=$db	
				fi
				# otherwise, there's no default yet, which is okay
			done

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

			# if dbc_dbtype isn't already set (from conf file) then
			# use the default as our best guess
			if [ ! "$dbc_dbtype" ]; then
				dbc_dbtype="$default_dbtype"
			fi
			db_set $dbc_package/database-type "$dbc_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_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 rdbms that support authentication
		if echo "$dbc_authenticated_dbtypes" | grep -q "$dbc_dbtype"; 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
		fi

		if echo "$dbc_fs_dbtypes" | grep -q "$dbc_dbtype"; then
			# if these haven't been specified, use defaults
			if [ ! "$dbc_basepath" ]; then 
				dbc_basepath="$dbc_default_basepath"; 
			fi
		fi

		if [ ! "$dbc_dbname" ]; then 
			dbc_dbname=`echo $dbc_package | tr -d +-.`; 
		fi

		# pre-seed any already defined values into debconf as defaults
		db_set $dbc_package/db/dbname "$dbc_dbname"
		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 echo "$dbc_authenticated_dbtypes" | grep -q "$dbc_dbtype"; then
			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_dbadmin" ]; then
				db_set $dbc_package/$dbc_dbtype/admin-user "$dbc_dbadmin"
			fi
		fi
		if echo "$dbc_remote_dbtypes" | grep -q "$dbc_dbtype"; then
			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_ssl" = "true" ] && [ "$dbc_dbtype" = "pgsql" ]; then
				db_set $dbc_package/pgsql/method "tcp/ip + ssl"
			fi
			db_input $dbc_remote_questions_priority $dbc_package/$dbc_dbtype/method || true
		fi
		if echo "$dbc_fs_dbtypes" | grep -q "$dbc_dbtype"; then
			# if these haven't been specified, use defaults
			if [ "$dbc_basepath" ]; then 
				db_set $dbc_package/db/basepath "$dbc_basepath"
			fi
		fi

	;;
	# state 4 - do stuff based on the connection method
	4)
		db_get $dbc_package/$dbc_dbtype/method && dbc_method="$RET"

		if echo "$dbc_remote_dbtypes" | grep -q "$dbc_dbtype"; then
			# 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
					test -f $f || continue
					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
		fi
	;;
	# state 5 - get host / port info if necessary
	5)
		if echo "$dbc_remote_dbtypes" | grep -q "$dbc_dbtype"; then
			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" ] || [ "$host" = "new host" ]; then
					# prompt them for a new hostname
					db_input high $dbc_package/remote/newhost || true
				fi
			fi
		fi
	;;
	# state 6 - do stuff based on host/port selection
	6)
		if echo "$dbc_remote_dbtypes" | grep -q "$dbc_dbtype"; then
			if [ "$dbc_method" != "unix socket" ]; then
				if [ ! "$host" ] || [ "$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 $dbc_remote_questions_priority $dbc_package/remote/port || true
			fi
		fi
	;;
	# state 7 - pgsql specific auth stuff, part 1
	7)
		if [ "$dbc_dbtype" = "pgsql" ] && [ ! "$dbc_frontend" ]; 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" ] && [ ! "$dbc_frontend" ]; then
			db_get $dbc_package/pgsql/authmethod-admin && authmethod_admin="$RET"
			# if we are using ident, we don't need passwords
			if [ "$authmethod_admin" = "ident" ]; then
				need_adminpw="false"
			fi
			# default the user auth method to the admin method
			# ...but only if the answer hasn't already been specified.
			if [ ! "${dbc_authmethod_user}" ]; then
				db_set $dbc_package/pgsql/authmethod-user "$authmethod_admin"
			fi
			db_input medium $dbc_package/pgsql/authmethod-user || true
		fi
	;;
	# state 9 - admin/app user/pass, dbname
	9)
		if echo "$dbc_authenticated_dbtypes" | grep -q "$dbc_dbtype"; then

			# who's the admin user
			if [ ! "$dbc_frontend" ]; then
				db_input $userdb_prio $dbc_package/$dbc_dbtype/admin-user || true
				if [ "$need_adminpw" != "false" ]; then
					dbc_get_admin_pass
				fi
			fi
			db_input $userdb_prio $dbc_package/db/app-user || true
			dbc_get_app_pass

		fi

		if echo "$dbc_fs_dbtypes" | grep -q "$dbc_dbtype"; then
			# check the path / permissions to install to
			db_input low $dbc_package/db/basepath || true
		fi

		# get the name of the database to use
		db_input $userdb_prio $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
	
	db_set $dbc_package/internal/skip-preseed true
}

dbc_migrate() {

	# if dbc_load_include is set, determine the format
	# and location of the old config file
	if [ "$dbc_load_include" ]; then
		iformat=`echo $dbc_load_include | cut -d: -f1`
		ifile=`echo $dbc_load_include | cut -d: -f2-`
	fi

	##
	## if they want to import settings from a previous 
	## non-dbc version, do that and mark the questions
	## skipped 
	##
	if [ -z "$ifile" ] || [ ! -f "$ifile" ]; then
		return
	fi

	dbc_logpart "migrating old settings into dbconfig-common: "
	if [ "$dbc_debug" ]; then
		_dbc_debug "dbconfig-load-include $dbc_load_include_args -f $iformat $ifile"
		dbconfig-load-include $dbc_load_include_args -f $iformat $ifile
	fi
	eval `dbconfig-load-include $dbc_load_include_args -f $iformat $ifile`
	if [ "$?" != "0" ]; then
		dbc_logline "failed"
		return
	fi

	# the load script needs to return at least a database type, if it's
	# not a single-dbtype package
	dbc_dbtype=${dbc_dbtype:-${dbc_hardcoded_dbtype:-}}
	if [ -z "$dbc_dbtype" ]; then
		dbc_logline "failed"
		return
	fi

	# if the dbtype is hardcoded, reset it no matter what
	# dbconfig-load-include tells us
	if [ "$dbc_hardcoded_dbtype" ]; then 
		dbc_dbtype="$dbc_hardcoded_dbtype"
	fi
	
	for f in database-type $dbc_dbtype/method db/dbname; do
		db_fset $dbc_package/$f seen true || true
	done
	if echo "$dbc_authenticated_dbtypes" | grep -q "$dbc_dbtype"; then
		for f in pgsql/authmethod-admin pgsql/authmethod-user $dbc_dbtype/admin-user db/app-user; do
			db_fset $dbc_package/$f seen true || true
		done
		db_set $dbc_package/db/app-user "$dbc_dbuser"
		db_set $dbc_package/$dbc_dbtype/app-pass "$dbc_dbpass"
		db_set $dbc_package/password-confirm "$dbc_dbpass"
	fi
	if echo "$dbc_remote_dbtypes" | grep -q "$dbc_dbtype"; then
		for f in remote/host remote/newhost remote/port ; do
			db_fset $dbc_package/$f seen true || true
		done
		db_set $dbc_package/remote/host "$dbc_dbserver"
		db_set $dbc_package/remote/newhost "$dbc_dbserver"
		db_set $dbc_package/remote/port "$dbc_dbport"
		if [ "$dbc_dbserver" ]; then
			db_set $dbc_package/$dbc_dbtype/method "tcp/ip"
		fi
	fi

	db_set $dbc_package/database-type $dbc_dbtype
	db_set $dbc_package/db/dbname "$dbc_dbname"

	dbc_logline "done"
}
