###
### load up common variables and functions
###
dbc_go(){
	local importing_from_non_dbc upgrading reconfiguring f tsubstfile upgrades_pending dbc_dumpfile _dbc_asuser reinstall

	. /usr/share/dbconfig-common/dpkg/common
	_dbc_debug "(postinst) dbc_go() $@"
	dbc_config $@
  # the maintainer has the option of telling us to not generate include files
  # for manual installs in case it changes the apps behavior to have the file
  dbc_dgi_on_manual=${dbc_dgi_on_manual:-true}

	###
	### begin main code execution
	###
	if [ "$dbc_command" = "configure" ] || [ "$dbc_command" = "reconfigure" ]; 
	then
		# read in debconf responses (which are seeded from the config)
		dbc_read_package_debconf
		# and write them to file.
		dbc_write_package_config
		# finally, re-read in the configuration from this file
		dbc_read_package_config

		###
		### if they don't want our help, quit
		###
		if [ "$dbc_install" != "true" ]; then return 0; fi

		# export the config file if it exists, for the scripts
		if [ "$dbc_generate_include" ]; then
			# strip the leading format string for convenience
			dbc_config_include=`echo "$dbc_generate_include" | sed -e 's/^[^:]*://'`
			export dbc_generate_include
			export dbc_config_include
		fi

		# find out if we're upgrading/reinstalling
		if [ "$dbc_oldversion" ]; then
			# read that little crumb left in config if we're reconfiguring
			db_get $dbc_package/internal/reconfiguring && reconfiguring="$RET"
			# and set it back to false
			db_reset $dbc_package/internal/reconfiguring
			# if not, we're definitely upgrading
			if [ "$reconfiguring" = "false" ]; then
				upgrading="yes"
			else
				db_get $dbc_package/dbconfig-reinstall && reinstall=$RET
				db_reset $dbc_package/dbconfig-reinstall
				# if they've said they don't want to reinstall stuff...
				if [ "$reinstall" = "false" ]; then return 0; fi
			fi
		fi

		# now, determine if we're upgrading from a non-dbc version.  if so,
		# there's a bunch of stuff that we do NOT want to do
		if [ "$upgrading" ] && [ "$dbc_first_version" ]; then
			if dpkg --compare-versions "$dbc_first_version" gt "$dbc_oldversion"; then
				dbc_logline "detected upgrade from previous non-dbconfig version"
				importing_from_non_dbc="true"
			fi
		fi

		# don't perform the following block of code during upgrades
		if [ ! "$upgrading" ]; then
			###
			### first things first, see if the database client package is installed,
			### and in case of failure provide a more sensible error message.
			###
			dbc_detect_installed_dbtype $dbc_dbtype || dbc_missing_db_package_error $dbc_dbclientpackage
			[ "$dbc_tried_again" ] && return 0

			###
			### next, if we're connecting to a local database,
			### see if the database server package is installed,
			### and in case of failure provide a more sensible error message.
			###
			if [ "$dbc_method" = "unix socket" ]; then
				$dbc_db_installed_cmd || dbc_missing_db_package_error $dbc_dbpackage
				[ "$dbc_tried_again" ] && return 0
			fi

			###
			### now, create the app user account
			###
			$dbc_createuser_cmd || dbc_install_error "creating user"
			[ "$dbc_tried_again" ] && return 0
	
			###
			### create the database
			###
			$dbc_createdb_cmd || dbc_install_error "creating database"
			[ "$dbc_tried_again" ] && return 0
	
			###
			### populate the database
			###
			# sqlfile is the file to use for installing the database
			dbc_sqlfile=$dbc_share/data/$dbc_basepackage/install/$dbc_dbtype
			dbc_sqlfile_adm=$dbc_share/data/$dbc_basepackage/install-dbadmin/$dbc_dbtype
			dbc_scriptfile=$dbc_share/scripts/$dbc_basepackage/install/$dbc_dbtype
			if [ -f "$dbc_scriptfile" ]; then
				dbc_logpart "populating database via scriptfile... "
				if ! sh -c "$dbc_scriptfile $*"; then
					dbc_error="$dbc_scriptfile exited with non-zero status"
					dbc_install_error "populating database"
					[ "$dbc_tried_again" ] && return 0
				fi
				dbc_logline "done"
			fi
			
			if [ -f "$dbc_sqlfile_adm" ]; then
				dbc_logpart "populating database via administrative sql... "
				if [ ! "$dbc_sql_substitutions" ]; then
					$dbc_sqlfile_cmd $dbc_sqlfile_adm || dbc_install_error "populating database with administrative sql"
				else
					tsubstfile=`dbc_mktemp`
					/usr/sbin/dbconfig-generate-include -f template -o template_infile=$dbc_sqlfile_adm $dbc_packageconfig > $tsubstfile
					$dbc_sqlfile_cmd $tsubstfile || dbc_install_error "populating database with administrative sql"
					rm -f $tsubstfile
				fi
				[ "$dbc_tried_again" ] && return 0
				dbc_logline "done"
			fi
			
			if [ -f "$dbc_sqlfile" ]; then
				dbc_logpart "populating database via sql... "
				_dbc_asuser="yes"
				if [ ! "$dbc_sql_substitutions" ]; then
					$dbc_sqlfile_cmd $dbc_sqlfile || dbc_install_error "populating database"
				else
					tsubstfile=`dbc_mktemp`
					/usr/sbin/dbconfig-generate-include -f template -o template_infile=$dbc_sqlfile $dbc_packageconfig > $tsubstfile
					$dbc_sqlfile_cmd $tsubstfile || dbc_install_error "populating database"
					rm -f $tsubstfile
				fi
				_dbc_asuser=""
				[ "$dbc_tried_again" ] && return 0
				dbc_logline "done"
			fi

			# now that we are sure that the database has been
			# (re-)installed, we can reset the purge flag.
			db_set $dbc_package/purge false
			db_fset $dbc_package/purge seen false
		fi	

		# end install/reconfigure section

		if [ "$importing_from_non_dbc" ]; then
			if ! $dbc_checkuser_command; then
				upgrade_error "importing dbconfig-settings"
				[ "$dbc_tried_again" ] && return 0
			fi
		fi

		# begin upgrade section

		if [ "$upgrading" ]; then

			upgrades_pending=`_dbc_find_upgrades`

			# if there are any upgrades to be applied
			if [ "$upgrades_pending" ]; then
				# ask if they want our help in the process at all
				db_set $dbc_package/dbconfig-upgrade $dbc_upgrade
				db_fset $dbc_package/dbconfig-upgrade seen false
				db_input high $dbc_package/dbconfig-upgrade || true
				db_go || true
				db_get $dbc_package/dbconfig-upgrade && dbc_upgrade="$RET"

				# and if they don't want our help, we'll go away
				if [ "$dbc_upgrade" != "true" ]; then return 0; fi

				# get the admin password if it's needed
				if echo "$dbc_authenticated_dbtypes" | grep -q "$dbc_dbtype"; then
					if [ ! "$dbc_frontend" ]; then
						if [ ! "$dbc_dbtype" = "pgsql" ] || [ ! "$dbc_authmethod_admin" = "ident" ]; then
							dbc_get_admin_pass
						fi
					fi
				fi

				# this is the file into which upgrade backups go
				dbc_dumpfile=/var/cache/dbconfig-common/backups/${dbc_package}_${dbc_oldversion}.$dbc_dbtype	
				dbc_logline "creating database backup in $dbc_dumpfile"
				# backup before we upgrade
				_dbc_asuser=""
				$dbc_dump_cmd $dbc_dumpfile || dbc_upgrade_error "backing up the old database"
			fi

			# now perform the updates
			for f in $upgrades_pending; do
				_dbc_apply_upgrades $f
			done

		fi
	# end upgrade section
	fi

	# don't forget to clean up after ourselves
	dbc_postinst_cleanup
}


##
## search through the predefined upgrade directories, and return
## the versions for which *some* upgrade is available.  later for each
## upgrade version with a script we again search through the predefined
## directories to find which upgrade provides it.  it's definitely
## less efficient this way, but it's much cleaner and ensures that
## upgrades are provided in-order regardless of which methods are used.
##
_dbc_find_upgrades(){
	local f s sqldir admsqldir scriptdir upgradedirs pending sorted placed tlist
	# check for new upgrades in these three locations
	sqldir=$dbc_share/data/$dbc_basepackage/upgrade/$dbc_dbtype
	admsqldir=$dbc_share/data/$dbc_basepackage/upgrade-dbadmin/$dbc_dbtype
	scriptdir=$dbc_share/scripts/$dbc_basepackage/upgrade/$dbc_dbtype

	for f in $sqldir $admsqldir $scriptdir; do
		if [ -d "$f" ]; then
			upgradedirs="${upgradedirs:+$upgradedirs }$f"
		fi
	done

	if [ ! "${upgradedirs:-}" ]; then return 0; fi

	for f in `find $upgradedirs -xtype f -print0 | \
              xargs --no-run-if-empty -0 -n1 basename | sort -n | uniq`; do
		if dpkg --compare-versions $dbc_oldversion lt $f; then
			pending="${pending:+$pending }$f"
		fi
	done

	# for each pending update
	for f in ${pending:-}; do
		# if the sorted list is empty
		if [ ! "${sorted:-}" ]; then
			sorted="$f"
		else
			# a scratch list for a sorted insert of the next version
			tlist=""
			# for each already sorted version
			for s in ${sorted:-}; do
				# if we haven't already placed it
				if [ ! "${placed:-}" ]; then
					# if the this version is less than the next sorted one
					if dpkg --compare-versions $f lt $s; then
						# insert it here
						tlist="$tlist $f"
						placed="yes"
					fi
				fi
				tlist="$tlist $s"
			done
			# if we still haven't placed it, tack it on to the end of the list
			if [ ! "${placed:-}" ]; then
				tlist="$tlist $f"
			fi
			# and now reset the placed variable, and update the sorted list
			placed=""
			sorted="$tlist"
		fi
	done

	echo $sorted
}

##
## this function applies all available upgrade scripts/sql for a specific
## version ($1).  no checking is done to make sure that the upgrade *should*
## be applied, that is assumed to have been done by _dbc_find_upgrades().
##
_dbc_apply_upgrades(){
	local f vers sqlfile admsqlfile scriptfile
	_dbc_debug "_dbc_apply_upgrades() $@"
	# check for new upgrades in these three locations
	vers="$1"
	sqlfile="$dbc_share/data/$dbc_basepackage/upgrade/$dbc_dbtype/$vers"
	admsqlfile="$dbc_share/data/$dbc_basepackage/upgrade-dbadmin/$dbc_dbtype/$vers"
	scriptfile="$dbc_share/scripts/$dbc_basepackage/upgrade/$dbc_dbtype/$vers"


	# now go through script updates
	if [ -f "$scriptfile" ]; then
		dbc_logline "applying upgrade script for $dbc_oldversion -> $vers"
		# XXX $*
		if ! sh -c "$scriptfile $*"; then
			dbc_error="$scriptfile exited with non-zero status"
			dbc_upgrade_error "processing $scriptfile"
			[ "$dbc_tried_again" ] && return 0
		fi
	fi
			
	_dbc_asuser=""
	if [ -f "$admsqlfile" ]; then
		dbc_logline "applying upgrade admin sql for $dbc_oldversion -> $vers"
		$dbc_sqlfile_cmd $admsqlfile || dbc_upgrade_error "processing $admsqlfile"
		[ "$dbc_tried_again" ] && return 0
	fi
			
	if [ -f "$sqlfile" ]; then
		_dbc_asuser="yes"
		dbc_logline "applying upgrade sql for $dbc_oldversion -> $vers"
		$dbc_sqlfile_cmd $sqlfile || dbc_upgrade_error "processing $sqlfile"
		[ "$dbc_tried_again" ] && return 0
		_dbc_asuser=""
	fi
}
