#!/bin/sh
#
# $Id$

${DEBUG:="false"} && set -xu
PROGNAME=`basename $0`

# LANG may cause trouble to access database
unset LANG

# Gfarm installation directory
prefix="/usr"
sysconfdir="/etc"
datarootdir="/usr/share"
datadir="/usr/share"
config_dir="${datadir}/gfarm/config"

PRIVATE_MODE=false

PATH="${prefix}/bin:${prefix}/sbin:/bin:/usr/bin:/sbin:/usr/sbin:/usr/ucb:/usr/pkg/bin:/usr/pkg/sbin:/usr/local/bin:/usr/local/sbin:$PATH"
export PATH
search_path="$PATH"

awk=awk
if [ -f /usr/bin/nawk ]; then awk=/usr/bin/nawk; fi

status=1
admin_password=/tmp/ap$$
password=/tmp/up$$
tmpfiles="$password $admin_password"
rm -f $password $admin_password
trap 'rm -f $tmpfiles; stty echo 2>/dev/null; exit $status' 0 1 2 15

getvalue()
{
	$awk '$1 == "'"$1"'" { print $2 }' $GFMD_CONF
}

update_usage_()
{
	return 1
}

usage()
{
	echo >&2 "usage: $PROGNAME [--help] [-t] [--update]"
	echo >&2 "	[-N]			- do not restart the server processes"
	echo >&2 "	[-r]			- enable metadata replication"
	echo >&2 "	[-d digest_type]	- specify digest type"
	echo >&2 "	[--prefix prefix]	- directory specified in config-gfarm"
	echo >&2 "	[-P backend_prefix]	- installation prefix of the backend program"
	echo >&2 "	[-l metadata_directory]	- backend database data directory"
	echo >&2 "	[-f backend_file]"
	echo >&2 "	[-o backend_option]"
	echo >&2 "	[-j metadb_journal_dir] - metadata journal directory"
	update_usage_$BACKEND_TYPE ||
		echo >&2 "	no option for backend=$BACKEND_TYPE"
	exit 1
}

update_sanity_()
{
	if $METADATA_REPLICATION; then
		if id _gfarmmd >/dev/null 2>&1; then :
		else
			echo "error: user _gfarmmd is not registered."
			return 1
		fi
	fi

	return 0
}

update_sanity()
{
	update_sanity_$BACKEND_TYPE
}

# most $BACKEND_TYPE calls the followings
# from display_backend_params_$BACKEND_TYPE, but some may not.
display_plain_param_backend_data_dir()
{
    echo     "metadata directory  [-l]: $BACKEND_DATA_DIR"
}

display_plain_param_backend_log_dir()
{
    return 0
}

tf2yn()
{
    case $1 in
    true) echo yes;;
    *)    echo no;;
    esac
}

tf2ed()
{
    case $1 in
    true) echo enable;;
    *)    echo disable;;
    esac
}

display_params()
{
    echo     "prefix [--prefix]: $CONFIG_PREFIX"
    echo     "metadata backend    [-b]: $BACKEND_TYPE"

    display_plain_params_backend_$BACKEND_TYPE
    display_plain_params_backend_port_$BACKEND_TYPE
    display_plain_params_backend_optional_$BACKEND_TYPE

    update_sanity
    echo "metadata replication         [-r]: `tf2yn $METADATA_REPLICATION`"
    if $METADATA_REPLICATION; then
        echo "metadata journal directory   [-j]: $METADATA_JOURNAL_DIR"
    fi
    echo "digest                       [-d]: $DIGEST_TYPE"
    exit 0
}

update_metadata_replication()
{
    if $METADATA_REPLICATION; then
	create_directory "$METADATA_JOURNAL_DIR"
	chmod 700 "$METADATA_JOURNAL_DIR"
    fi

    tmp=`mktemp` || ABORT "cannot create a tmp file to update $GFMD_CONF"
    egrep -v '(metadb_replication|metadb_journal_dir)' $GFMD_CONF > $tmp &&
    echo "metadb_replication `tf2ed $METADATA_REPLICATION`" >> $tmp &&
    echo "# mkdir following directory when metadb_replication is set to enable." >> $tmp &&
    echo "metadb_journal_dir $METADATA_JOURNAL_DIR" >> $tmp &&
    mv $tmp $GFMD_CONF || {
	rm -f $tmp
	ABORT "cannot update $GFMD_CONF"
    }
}

update_digest()
{
    if [ X"$DIGEST_TYPE" != X ]; then
	tmp=`mktemp` || ABORT "cannot create a tmp file to update $GFMD_CONF"
	egrep -v '^digest ' $GFMD_CONF > $tmp &&
	echo "digest $DIGEST_TYPE" >> $tmp &&
	mv $tmp $GFMD_CONF || {
	    rm -f $tmp
	    ABORT "cannot update $GFMD_CONF"
	}
    fi
}

update_gfmd_failover_conf()
{
    if $METADATA_REPLICATION; then
	if [ ! -f $GFMD_FAILOVER_CONF ]; then
	    mkcnf "$GFMD_FAILOVER_CONF" \
		cat "$config_dir/gfmd.failover.conf"
	    chmod 600 "$GFMD_FAILOVER_CONF"
	fi
	if [ ! -f $GFMD_FAILOVER_AGENT_CONF ]; then
	    mkcnf "$GFMD_FAILOVER_AGENT_CONF" \
		cat "$config_dir/gfmd.failover.agent.conf"
	    chmod 600 "$GFMD_FAILOVER_AGENT_CONF"
	fi
    fi
}

update_first_set_param()
{
    METADATA_REPLICATION_ED=`getvalue metadb_replication`
    if [ X"$METADATA_REPLICATION_ED" = X"enable" ]; then
        : ${METADATA_REPLICATION:=true}
    else
        : ${METADATA_REPLICATION:=false}
    fi

    : ${METADATA_JOURNAL_DIR:=`getvalue metadb_journal_dir`}
    : ${METADATA_JOURNAL_DIR:="$CONFIG_PREFIX/var/gfarm-metadata/journal"}

    : ${DIGEST_TYPE=`getvalue digest`}
}

# do this first, ABORT() is defined here
. $config_dir/config-gfarm.common

#
# parse arguments
#

: ${BACKEND_OPTIONS:=}
: ${BACKEND_TYPE:=}

while [ $# -gt 0 ] ; do
	case $1 in

	# set parameters
	  --prefix) shift; [ $# -ge 1 ] || usage
		CONFIG_PREFIX=$1
		;;
	  -P) shift; [ $# -ge 1 ] || usage
		BACKEND_PREFIX=$1
		;;
	  -l) shift; [ $# -ge 1 ] || usage
		BACKEND_DATA_DIR=$1
		;;
	  -f) shift; [ $# -ge 1 ] || usage
		BACKEND_OPTIONS="$BACKEND_OPTIONS -f $1"
		;;
	  -o) shift; [ $# -ge 1 ] || usage
		BACKEND_OPTIONS="$BACKEND_OPTIONS $1"
		;;
	  -j) shift; [ $# -ge 1 ] || usage
		METADATA_JOURNAL_DIR=$1
		;;

	# control options
	  --help)
		usage
		;;
	  -N)
		START_SERVICE=false
		;;
	  -t)
		DISPLAY_PARAMS=true
		;;
	  -r)
		METADATA_REPLICATION=true
		;;
	  -d) shift; [ $# -ge 1 ] || usage
		DIGEST_TYPE=$1
		;;
	  --update|--update-symlink)
		UPDATE=true
		;;

	# XXX postgresql backend dependent option
	  -X)
		SUPPORT_XML_TYPE=yes
		;;
	  *)
		usage
		;;
	esac
	shift
done

: ${CONFIG_PREFIX:=}
if [ X"$CONFIG_PREFIX" != X ]; then
	: ${GFARM_CONF_DIR:="$CONFIG_PREFIX/etc"}
else
	: ${GFARM_CONF_DIR:="$sysconfdir"}
fi
: ${GFMD_CONF:="$GFARM_CONF_DIR/gfmd.conf"}

# do not make these two files customizable,
# that introduces extra complexity to config-gfarm-update
GFMD_FAILOVER_CONF="`dirname $GFMD_CONF`/gfmd.failover.conf"
GFMD_FAILOVER_AGENT_CONF="`dirname $GFMD_FAILOVER_CONF`/gfmd.failover.agent.conf"

# sanity check
if [ ! -f ${GFMD_CONF} ]; then
	ABORT "cannot find ${GFMD_CONF}, --prefix option required"
fi

# determine a backend database type
if grep '^[ 	]*postgresql_server_host[ 	]' ${GFMD_CONF} >/dev/null
then
	BACKEND_TYPE=postgresql
elif grep '^[ 	]*ldap_server_host[ 	]' ${GFMD_CONF} >/dev/null
then
	BACKEND_TYPE=ldap
else
	BACKEND_TYPE=none
fi

# load backend-dependent functions
. $config_dir/config-gfarm.$BACKEND_TYPE
. $config_dir/config-gfarm-update.$BACKEND_TYPE

#
# search default $BACKEND_PREFIX
#

set_default_backend_prefix_$BACKEND_TYPE
. $config_dir/config-gfarm.sysdep

#
# default values
#

set_first_defaults_$BACKEND_TYPE
sysdep_defaults

: ${DISPLAY_PARAMS:=false}
: ${START_SERVICE:=true}
: ${UPDATE:=false}

update_first_set_param
update_first_set_param_$BACKEND_TYPE
set_last_defaults_$BACKEND_TYPE
update_last_set_param_$BACKEND_TYPE

update_sanity || ABORT "aborted"

# -t option; display parameters
$DISPLAY_PARAMS && display_params

update_postprocess_$BACKEND_TYPE || ABORT "aborted"

#
if $UPDATE; then
	update_metadata_replication
	update_digest
	update_$BACKEND_TYPE
	update_gfmd_failover_conf
else
	update_access_db_$BACKEND_TYPE $BACKEND_OPTIONS
fi

status=0
# trap action automatically returns this $status as exit code
