#!/bin/bash
#
#
#   OPEN-XCHANGE legal information
#
#   All intellectual property rights in the Software are protected by
#   international copyright laws.
#
#
#   In some countries OX, OX Open-Xchange, open xchange and OXtender
#   as well as the corresponding Logos OX Open-Xchange and OX are registered
#   trademarks of the Open-Xchange, Inc. group of companies.
#   The use of the Logos is not covered by the GNU General Public License.
#   Instead, you are allowed to use these Logos according to the terms and
#   conditions of the Creative Commons License, Version 2.5, Attribution,
#   Non-commercial, ShareAlike, and the interpretation of the term
#   Non-commercial applicable to the aforementioned license is published
#   on the web site http://www.open-xchange.com/EN/legal/index.html.
#
#   Please make sure that third-party modules and libraries are used
#   according to their respective licenses.
#
#   Any modifications to this package must retain all copyright notices
#   of the original copyright holder(s) for the original code used.
#
#   After any such modifications, the original and derivative code shall remain
#   under the copyright of the copyright holder(s) and/or original author(s)per
#   the Attribution and Assignment Agreement that can be located at
#   http://www.open-xchange.com/EN/developer/. The contributing author shall be
#   given Attribution for the derivative code and a license granting use.
#
#    Copyright (C) 2004-2013 Open-Xchange, Inc.
#    Mail: info@open-xchange.com
#
#
#    This program is free software; you can redistribute it and/or modify it
#    under the terms of the GNU General Public License, Version 2 as published
#    by the Free Software Foundation.
#
#    This program is distributed in the hope that it will be useful, but
#    WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
#    or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
#    for more details.
#
#    You should have received a copy of the GNU General Public License along
#    with this program; if not, write to the Free Software Foundation, Inc., 59
#    Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
#

OXFUNCTIONS=/opt/open-xchange/lib/oxfunctions.sh
CONFDIR=/opt/open-xchange/etc

test -f $OXFUNCTIONS || {
    echo "missing common shell functions file"
    exit 1
}

. $OXFUNCTIONS

OXHOST=$(hostname -f)
if [ -z "$OXHOST" ]; then
    die "unable to determine hostname using 'hostname -f', giving up."
fi

if hostname --help 2>&1 | grep all-ip-addresses > /dev/null; then
    # on at least Debian Squeeze like systems, -i results in crap
    HCMD="hostname --all-ip-addresses"
    haddrs=( $($HCMD) )
    OXIP=${haddrs[0]}
else
    HCMD="hostname -i"
    OXIP=$($HCMD)
fi
if [ -z "$OXIP" ]; then
    die "unable to determine host ip using $HCMD, giving up."
fi

# some defaults
SERVER_NAME=
SERVER_NAME_LONG=servername
IMAP_SERVER="$OXHOST"
IMAP_SERVER_LONG=imapserver
SMTP_SERVER="$OXHOST"
SMTP_SERVER_LONG=smtpserver
LOGIN_SOURCE=login
LOGIN_SOURCE_LONG=mail-login-src
LOGIN_SOURCE_VALUES="login mail name"
MAIL_SERVER_SOURCE=user
MAIL_SERVER_SOURCE_LONG=mail-server-src
MAIL_SERVER_SOURCE_VALUES="user global"
TRANSPORT_SERVER_SOURCE=user
TRANSPORT_SERVER_SOURCE_LONG=transport-server-src
TRANSPORT_SERVER_SOURCE_VALUES="user global"
SERVER_MEMORY=
SERVER_MEMORY_LONG=servermemory
CLT_MEMORY=50
CLT_MEMORY_LONG=clt-memory
TMPDIR_PATH=/var/spool/open-xchange/uploads
TMPDIR_PATH_LONG=tmpdir-path
AJP_JVM_ROUTE=APP1
AJP_JVM_ROUTE_LONG=jkroute
MAXSESSION=0
MAXSESSION_LONG=maxSession
SESSIONDEFAULTLIFETIME=3600000
SESSIONDEFAULTLIFETIME_LONG=sessionDefLifeTime
ADD_LICENSE=
ADD_LICENSE_LONG=add-license
NO_LICENSE=
NO_LICENSE_LONG=no-license
CONFIGDB_USER=openexchange
CONFIGDB_USER_LONG=configdb-user
CONFIGDB_PASS=
CONFIGDB_PASS_LONG=configdb-pass
CONFIGDB_READ=localhost
CONFIGDB_READ_LONG=configdb-readhost
CONFIGDB_WRITE=$CONFIGDB_READ
CONFIGDB_WRITE_LONG=configdb-writehost
CONFIGDB_READ_PORT=3306
CONFIGDB_READ_PORT_LONG=configdb-readport
CONFIGDB_WRITE_PORT=$CONFIGDB_READ_PORT
CONFIGDB_WRITE_PORT_LONG=configdb-writeport
CONFIGDB_DBNAME=configdb
CONFIGDB_DBNAME_LONG=configdb-dbname
MASTER_PASS=
MASTER_PASS_LONG=master-pass
MASTER_USER=oxadminmaster
MASTER_USER_LONG=master-user
DISABLE_RMI_AUTH=
DISABLE_RMI_AUTH_LONG=disableauth
URL="http://$OXHOST/"
URL_LONG=extras-link
OXOBJECT_LINK_HOSTNAME="$OXHOST"
OXOBJECT_LINK_HOSTNAME_LONG=object-link-hostname
OXCLUSTERNAME="$OXHOST"
OXCLUSTERNAME_LONG=name-of-oxcluster
NETWORK_LISTENER_HOST=localhost
NETWORK_LISTENER_HOST_LONG=network-listener-host
# AJP_BIND_ADDR_LONG kept for compatibility
AJP_BIND_ADDR_LONG=ajp-bind-port

MUSTOPTS="SERVER_NAME CONFIGDB_PASS OXOBJECT_LINK_HOSTNAME SERVER_MEMORY OXCLUSTERNAME"
LONGOPTS='$SERVER_NAME_LONG:,$IMAP_SERVER_LONG:,$SMTP_SERVER_LONG:,$LOGIN_SOURCE_LONG:,$MAIL_SERVER_SOURCE_LONG:,$TRANSPORT_SERVER_SOURCE_LONG:,$CONFIGDB_USER_LONG:,$CONFIGDB_PASS_LONG:,$CONFIGDB_READ_LONG:,$CONFIGDB_WRITE_LONG:,$CONFIGDB_DBNAME_LONG:,$SERVER_MEMORY_LONG:,$CLT_MEMORY_LONG:,$CONFIGDB_READ_PORT_LONG:,$CONFIGDB_WRITE_PORT_LONG:,$TMPDIR_PATH_LONG:,$MASTER_PASS_LONG:,$MASTER_USER_LONG:,$AJP_JVM_ROUTE_LONG:,$OXOBJECT_LINK_HOSTNAME_LONG:,$URL_LONG:,$MAXSESSION_LONG:,$SESSIONDEFAULTLIFETIME_LONG:,$DISABLE_RMI_AUTH_LONG,$NO_LICENSE_LONG,$ADD_LICENSE_LONG:,$OXCLUSTERNAME_LONG:,$NETWORK_LISTENER_HOST_LONG:,$AJP_BIND_ADDR_LONG:'

usage() {
    echo
    echo "$0 currently knows the following parameters:"
    echo
    local lopts=$(echo $LONGOPTS | sed -e 's/[:,]/ /g')
    printf '%-23s | %-45s | %-s\n' "Parameter" "Default value" "Possible values"
    echo "--------------------------------------------------------------------------------------------"
    for opt in $lopts; do
	local rvar=${opt%_LONG}
	GLOBIGNORE='*'
	local default="$(eval echo "$rvar")"
	local possible=$(eval echo ${opt%_LONG}_VALUES)
	local lopt=$(eval echo $opt)
        # echo $opt $rvar $default $lopt
	printf '%-23s | %-45s | %-s\n' "--$lopt" $default "$possible"
	GLOBIGNORE=
    done
    cat<<EOF

Example:

  $0 --servername=ox6 --configdb-pass=secret --master-pass=secret --add-license=f-o-o-b-a-r --servermemory 512 --name-of-oxcluster myoxcluster

use -D for Debug mode

EOF
    echo
}

v_setprop() {
    local prop="$1"
    local val="$2"
    local propfile="$3"
    if [ -f $3 ]; then 
        # echo setting $prop in $propfile
        echo -n .
        ox_set_property "$prop" "$val" "$propfile"
    else
	echo
        echo skipping configuration of $1 in $3
    fi
}

v_comment() {
    local prop="$1"
    local action="$2"
    local propfile="$3"
    if [ -f $3 ]; then
        # echo $action hash for $prop in $propfile
	echo -n .
	ox_comment "$prop" "$action" "$propfile"
    else
	echo
	echo skipping configuration of $i in $3
    fi
}

handleIPv6() {
    if [[ "$1" =~ .*:.* ]]; then
	echo "[$1]"
    else
	echo $1
    fi
}

setup() 
{
    #
    # groupware configuration files
    #

    echo setting up open-xchange configuration ${CONFDIR}

    CUROPTS=$(eval ox_read_property JAVA_XTRAOPTS ${CONFDIR}/ox-scriptconf.sh)
    CUROPTS=$(echo $CUROPTS | sed -e 's/"//g' -e 's/-Xmx[0-9]\+[Mm]*[ ]*//')
    SERVEROPTS="$CUROPTS -Xmx${SERVER_MEMORY}m"

    v_setprop JAVA_XTRAOPTS "\"$SERVEROPTS\"" ${CONFDIR}/ox-scriptconf.sh

    GLOBIGNORE='*'
    v_setprop com.openexchange.server.backendRoute "$AJP_JVM_ROUTE" ${CONFDIR}/server.properties
    v_setprop com.openexchange.connector.networkListenerHost "$NETWORK_LISTENER_HOST" ${CONFDIR}/server.properties
    GLOBIGNORE=

    v_setprop object_link "http://$OXOBJECT_LINK_HOSTNAME/#m=[module]&i=[object]&f=[folder]" ${CONFDIR}/notification.properties

    v_setprop URL "$URL" ${CONFDIR}/configjump.properties



    SQLHOST=$(handleIPv6 $CONFIGDB_READ)
    SQLPORT=$CONFIGDB_READ_PORT
    EVAL_SQL_URL=$(eval echo $SQL_URL)
    v_setprop readUrl $EVAL_SQL_URL ${CONFDIR}/configdb.properties

    SQLHOST=$(handleIPv6 $CONFIGDB_WRITE)
    SQLPORT=$CONFIGDB_WRITE_PORT
    EVAL_SQL_URL=$(eval echo $SQL_URL)
    v_setprop writeUrl $EVAL_SQL_URL ${CONFDIR}/configdb.properties

    if [ "$CONFIGDB_READ" != "$CONFIGDB_WRITE" ]; then
	v_setprop useSeparateWrite "true" ${CONFDIR}/configdb.properties
    fi

    v_setprop readProperty.1 "user=$CONFIGDB_USER" ${CONFDIR}/configdb.properties
    v_setprop readProperty.2 "password=$CONFIGDB_PASS" ${CONFDIR}/configdb.properties

    v_setprop writeProperty.1 "user=$CONFIGDB_USER" ${CONFDIR}/configdb.properties
    v_setprop writeProperty.2 "password=$CONFIGDB_PASS" ${CONFDIR}/configdb.properties

    v_setprop SERVER_NAME $SERVER_NAME ${CONFDIR}/system.properties

    v_setprop com.openexchange.mail.mailServer $IMAP_SERVER ${CONFDIR}/mail.properties
    v_setprop com.openexchange.mail.transportServer $SMTP_SERVER ${CONFDIR}/mail.properties
    v_setprop com.openexchange.mail.loginSource $LOGIN_SOURCE ${CONFDIR}/mail.properties
    v_setprop com.openexchange.mail.passwordSource session ${CONFDIR}/mail.properties
    v_setprop com.openexchange.mail.mailServerSource $MAIL_SERVER_SOURCE ${CONFDIR}/mail.properties
    v_setprop com.openexchange.mail.transportServerSource $TRANSPORT_SERVER_SOURCE ${CONFDIR}/mail.properties

    v_setprop UPLOAD_DIRECTORY "$TMPDIR_PATH" ${CONFDIR}/server.properties

    v_setprop com.openexchange.sessiond.maxSession "$MAXSESSION" ${CONFDIR}/sessiond.properties
    v_setprop com.openexchange.sessiond.sessionDefaultLifeTime "$SESSIONDEFAULTLIFETIME" ${CONFDIR}/sessiond.properties

    v_setprop com.openexchange.hazelcast.group.name $OXCLUSTERNAME ${CONFDIR}/hazelcast.properties

    #
    # administration configuration files
    #

    CUROPTS=$(eval ox_read_property JAVA_OXCMD_OPTS ${CONFDIR}/ox-scriptconf.sh)
    CUROPTS=$(echo $CUROPTS | sed -e 's/"//g' -e 's/-Xmx[0-9]\+[Mm]*[ ]*//')
    CLTOPTS="$CUROPTS -Xmx${CLT_MEMORY}m"

    v_setprop JAVA_OXCMD_OPTS "\"$CLTOPTS\"" ${CONFDIR}/ox-scriptconf.sh

    if [ -z "$DISABLE_RMI_AUTH" ] ; then
        v_setprop MASTER_AUTHENTICATION_DISABLED false ${CONFDIR}/AdminDaemon.properties
        v_setprop CONTEXT_AUTHENTICATION_DISABLED false ${CONFDIR}/AdminDaemon.properties
        echo
        echo "*** RMI authentication is enabled"
        if [ -z "$MASTER_PASS" ]; then
            die "ERROR: master password cannot be null if authentication is enabled"
        else
            echo "using $MASTER_USER as master account"
            /opt/open-xchange/sbin/generatempasswd -A $MASTER_USER \
		-f /opt/open-xchange/etc/mpasswd -P "$MASTER_PASS" >/dev/null
        fi
    else
        v_setprop MASTER_AUTHENTICATION_DISABLED true ${CONFDIR}/AdminDaemon.properties
        v_setprop CONTEXT_AUTHENTICATION_DISABLED true ${CONFDIR}/AdminDaemon.properties
        echo
        echo "*** RMI authentication is disabled"
    fi
}

addLicense() {
    local lic=$1
    local nr=$2
    echo "adding $lic"
    echo "com.openexchange.licensekey.${nr}=$lic" >> $LICENSEFILE
}


TEMP=$(POSIXLY_CORRECT=true getopt -o hD --long "$(eval echo $LONGOPTS),help" -- "$@") \
    || die "exiting"

eval set -- "$TEMP"

while true; do
    case "$1" in
	--$SERVER_NAME_LONG)
          SERVER_NAME=$2
          shift 2
          ;;
	--$IMAP_SERVER_LONG)
          IMAP_SERVER=$2
          shift 2
          ;;
	--$SMTP_SERVER_LONG)
          SMTP_SERVER=$2
          shift 2
          ;;
	--$LOGIN_SOURCE_LONG)
          LOGIN_SOURCE=$2
          shift 2
          ;;
	--$MAIL_SERVER_SOURCE_LONG)
          MAIL_SERVER_SOURCE=$2
          shift 2
          ;;
	--$TRANSPORT_SERVER_SOURCE_LONG)
          TRANSPORT_SERVER_SOURCE=$2
          shift 2
          ;;
	--$CONFIGDB_USER_LONG)
          CONFIGDB_USER=$2
          shift 2
          ;;
	--$CONFIGDB_PASS_LONG)
          CONFIGDB_PASS=$2
          shift 2
          ;;
	--$CONFIGDB_READ_LONG)
          CONFIGDB_READ=$2
          shift 2
          ;;
	--$CONFIGDB_WRITE_LONG)
          CONFIGDB_WRITE=$2
          shift 2
          ;;
	--$CONFIGDB_READ_PORT_LONG)
          CONFIGDB_READ_PORT=$2
          shift 2
          ;;
	--$CONFIGDB_WRITE_PORT_LONG)
          CONFIGDB_WRITE_PORT=$2
          shift 2
          ;;
	--$CONFIGDB_DBNAME_LONG)
          CONFIGDB_DBNAME=$2
          shift 2
          ;;
	--$SERVER_MEMORY_LONG)
          SERVER_MEMORY=$2
          shift 2
          ;;
	--$CLT_MEMORY_LONG)
          CLT_MEMORY=$2
          shift 2
          ;;
	--$TMPDIR_PATH_LONG)
          TMPDIR_PATH=$2
          shift 2
          ;;
	--$MASTER_PASS_LONG)
          MASTER_PASS=$2
          shift 2
          ;;
	--$MASTER_USER_LONG)
          MASTER_USER=$2
          shift 2
          ;;
	--$DISABLE_RMI_AUTH_LONG)
          DISABLE_RMI_AUTH=true
          shift
          ;;
	--$AJP_JVM_ROUTE_LONG)
          AJP_JVM_ROUTE=$2
          shift 2
          ;;
	--$AJP_BIND_ADDR_LONG)
          NETWORK_LISTENER_HOST=$2
          shift 2
          ;;
	--$NETWORK_LISTENER_HOST_LONG)
          NETWORK_LISTENER_HOST=$2
          shift 2
          ;;
	--$OXOBJECT_LINK_HOSTNAME_LONG)
          OXOBJECT_LINK_HOSTNAME=$2
          shift 2
          ;;
	--$URL_LONG)
          URL=$2
          shift 2
          ;;
	--$MAXSESSION_LONG)
          MAXSESSION=$2
          shift 2
          ;;
	--$SESSIONDEFAULTLIFETIME_LONG)
          SESSIONDEFAULTLIFETIME=$2
          shift 2
          ;;
	--$ADD_LICENSE_LONG)
          ADD_LICENSE=$2
          shift 2
          ;;
	--$NO_LICENSE_LONG)
          NO_LICENSE=true
          shift
          ;;
	--$OXCLUSTERNAME_LONG)
          OXCLUSTERNAME=$2
          shift 2
          ;;
	-h|--help)
          usage
          exit
          shift
          ;;
	-D)
          set -x
          shift
          ;;
	--)
          shift
          break
          ;;
	*)
          die "Internal error!"
          exit 1
          ;;
    esac
done

if [ $(id -u) -ne 0 ]; then
    die "need to be root in order to setup the system"
fi

if [ -z "$NO_LICENSE" ]; then
    MUSTOPTS="$MUSTOPTS ADD_LICENSE"
fi

# generic parameter checking
for opt in $MUSTOPTS; do
    opt_var=$(eval echo \$$opt)
    opt_var_long=$(eval echo \$${opt}_LONG)
    if [ -z "$opt_var" ]; then
        usage;
	die "missing required option --$opt_var_long"
    fi
done

# generic option checking
ALLOPTS=$(echo $LONGOPTS | sed -e 's/[$:,]/ /g' -e 's/_LONG//g')
for opt in $ALLOPTS; do
    opt_var=$(eval echo \$$opt)
    opt_var_long=$(eval echo \$${opt}_LONG)
    opt_var_values=$(eval echo \$${opt}_VALUES)
    if [ -n "$opt_var_values" ]; then
	found=
	for val in $opt_var_values; do
	    if [ "$val" == "$opt_var" ]; then
		found=$val
	    fi
	done
	if [ -z "$found" ]; then
	    die "\"$opt_var\" is not a valid option to --$opt_var_long"
	fi
    fi
done

for mem in SERVER_MEMORY CLT_MEMORY; do
    MEMMEM=$(eval echo \$$mem)
    if [ -n "$(echo $MEMMEM | sed -e 's;[0-9];;g')" ]; then
        die "$MEMMEM is not an allowed value for --$(eval echo \$${mem}_LONG), must be a number > 0"
    fi
done

SQL_URL="jdbc:mysql://\$SQLHOST:\$SQLPORT/\$SQLDB"
SQLDB=$CONFIGDB_DBNAME
SQLOPTS=$SQLOPTS
LICENSEFILE="/opt/open-xchange/etc/licensekeys.properties"


# license file ops
if [ -n "$ADD_LICENSE" ]; then
    if [ ! -e $LICENSEFILE ]; then
	addLicense "$ADD_LICENSE" 1
    else
	if ! grep "$ADD_LICENSE" $LICENSEFILE >/dev/null; then
	    cnt=1
	    while [ true ]; do
		lstr="com.openexchange.licensekey.${cnt}"
		if ! grep -E "^$lstr" $LICENSEFILE > /dev/null; then
		    addLicense "$ADD_LICENSE" $cnt
		    break
		fi
		cnt=$(( $cnt + 1 ))
	    done
	else
	    echo "skipping license $ADD_LICENSE, it's already in $LICENSEFILE"
	fi
    fi
fi

if [ -d ${CONFDIR} ]; then
    setup
    echo
    echo "open-xchange daemon must now be restarted if already running"
else
    echo ${CONFDIR} not available skipping open-xchange configuration
fi
