#!/bin/sh
#
# Atmail calendar server installation script
#
# Copyright (c) 2009 - Atmail
#
# Author : Brett Embery
#

install_file="cp"
install_folder="cp -r";
atmail_dir="/usr/local/atmail/webmail/config"
atmail_client_dir="/var/www/html/atmail/webmail/config"
calendar_dir="/usr/local/atmail/calendarserver"
calendar_port="8008";
debian=0;
wd="$(cd "$(dirname "$0")" && pwd)";
logdir="${wd}/install_logs";

# prep the log dir/files
if [ -d "${logdir}" ]
	then
	rm -rf "${logdir}"
fi
mkdir -p "${logdir}";

if [ -f '/etc/debian_version' ]
	then
	debian=1;
fi

if [ -f '/etc/debian_release' ]
	then
	debian=1;
fi

#verbose="> $calendar_dir/install.log"

# Change the working directory
if [ -d /usr/local/atmail/server_source/calendar_server ]
	then
	cd /usr/local/atmail/server_source/calendar_server/
fi

# ********* test command line args **********


if [ $4 ]
	then
	echo
else
	echo "Please run calserver-install.php"
	exit
fi

if [ $1 ]
	then
	if [ $5 ]
		then
		echo
	else
		atmail_dir=$1
	fi
else
	echo 
	echo "================================"
	echo "Atmail Calendar Server Installer"
	echo "================================"

	# ********** ask for directory configuration **********
	read -p "Please specify the config directory of Atmail (default is $atmail_dir):" t1
	if [ -n "$t1" ]
		then
		atmail_dir="$t1"
	fi
fi

if [ $5 ]
	then

	echo

	#atmail_dir="/var/www/html/atmail/webmail/config"
	# ********** ask for directory configuration **********

	read -p "Please specify the config directory of Atmail:" t1

	if [ -n "$t1" ]
		then
		atmail_dir="$t1"
	fi
fi


if [ $2 ]
	then
	echo "Install directory $2"
	calendar_dir=$2
else
	read -p "Please specify the installation directory for Calendar server (default is $calendar_dir):" t1
	if [ -n "$t1" ]
		then
		calendar_dir="$t1"
	fi
fi

if [ $3 ]
	then
	echo "Port $calendar_port"
	calendar_port=$3
else
	# ************ ask for ports to use *************
	read -p "Please specify the port to listen on (default is $calendar_port):" t1
	if [ -n "$t1" ]
		then
		calendar_port="$t1"
	fi
fi

calendar_port2=$(( $calendar_port + 1 ));
calendar_port3=$(( $calendar_port + 2 ));
calendar_port_ssl=8443

# Build the install.log file
# echo "Install log" > $calendar_dir/install.log

# ************* ask for admin password *************
#read -p "Please specify the administrator password:" -e t1
#if [ -n "$t1" ]
#then
#	admin_pass="$t1"
#else
#	echo "Administrator password cannot be blank."
#	exit;
#fi
#exit

# ************* sanity check user input *************
# ************* look for dbconfig.ini  *************
echo
echo "** Sanity Check **"
echo
echo -n "Checking for dbconfig.ini..."
if [ -f $atmail_dir/dbconfig.ini ]
	then
	chown atmail:atmail $atmail_dir/dbconfig.ini
	chmod 775 $atmail_dir/dbconfig.ini
	echo "Ok"
else
	echo "Cannot locate dbconfig.ini or invalid Atmail configuration directory specified: $atmail_dir"
	exit;
fi

# ************* sanity check user ports availablity *************
foundPortRange=0
while [ $foundPortRange -eq 0 ]
do
	echo -n "Checking availability of server ports ($calendar_port, $calendar_port2, $calendar_port3, $calendar_port_ssl)..."
	port1=$(netstat -ltn | grep $calendar_port | wc -l);
	port2=$(netstat -ltn | grep $calendar_port2 | wc -l);
	port3=$(netstat -ltn | grep $calendar_port3 | wc -l);
	portssl=$(netstat -ltn | grep $calendar_port_ssl | wc -l);

	ports=0
	if [ $port1 != 0 ]
		then
		ports=1
	fi

	if [ $port2 != 0 ]
		then
		ports=1
	fi

	if [ $port3 != 0 ]
		then
		ports=1
	fi

	if [ $portssl != 0 ]
		then
		ports=1
	fi

	if [ $ports -eq 0 ]
		then
		echo "Ok"
		echo $calendar_port > ./.port_in_use
		foundPortRange=1
	else
		if [ $port1 != 0 ]
			then
			echo "$calendar_port is in use."
			calendar_port=`expr $calendar_port + 1`
			calendar_port2=`expr $calendar_port2 + 1`
			calendar_port3=`expr $calendar_port3 + 1`			
		fi 
		if [ $port2 != 0 ]
			then
			echo "$calendar_port2 is in use."
			calendar_port=`expr $calendar_port + 2`
			calendar_port2=`expr $calendar_port2 + 2`
			calendar_port3=`expr $calendar_port3 + 2`			
		fi 
		if [ $port3 != 0 ]
			then
			echo "$calendar_port3 is in use."
			calendar_port=`expr $calendar_port + 3`
			calendar_port2=`expr $calendar_port2 + 3`
			calendar_port3=`expr $calendar_port3 + 3`
		fi 
		if [ $portssl != 0 ]
			then
			echo "$calendar_port_ssl is in use."
			calendar_port_ssl=`expr $calendar_port_ssl + 1`
		fi 
	fi
done

# ************* install deps *************
if [ $4 ]
	then
	echo "Dependency check skipped."
else
	echo "Installing dependencies..."
	yum install rsync attr gcc krb5-devel e2fsprogs-devel libidn-devel subversion zlib-devel openssl openssl-devel sqlite-devel gcc-c++ autoconf automake ncurses-devel python-devel readline-devel php-xml ${verbose}
fi


# ************* sanity check atmail user/group *************
echo -n "Checking for Atmail user and group..."
USER_EXISTS=`id atmail | grep "atmail" | wc -l`
if [ $USER_EXISTS -ne 1 ]
	then
	USER_EXISTS=`id atmail | grep "3000" | wc -l`
	if [ $USER_EXISTS -ne 1 ]
		then
		echo "Make sure user/group atmail:atmail exists !"
		exit;
	else
		echo "Ok"
	fi
else
	echo "Ok"
fi

echo -n "Checking file system write..."
touch write_test
if [ -f write_test ]
	then 
	echo "OK"
else
	echo "Failed to write to file system!"
	exit;
fi

echo -n "Checking for file system xattr support..."

# test for xattr support
touch xattr_test
if [ -f /usr/bin/attr ]
	then
	attr -s test -V 1 xattr_test 2>&1 > /dev/null
	xattr_support=`attr -l xattr_test 2>&1 | wc -l`
else 
	if [ -f /usr/bin/xattr ]
		then
		xattr -s test -V 1 xattr_test 2>&1 > /dev/null
		xattr_support=`xattr -l xattr_test 2>&1 | wc -l`
	else
		echo "UNABLE TO DETERMINE IF EXTENDED ATTRIBUTE SUPPORT IS ENABLED ON TARGET FILE SYSTEM."
	fi
fi

if [ "${xattr_support}" = "0" ]
	then
	if [ -f $calendar_dir/../calserver.img ]
		then
		echo "Found existing calendar server image."
		mount -o loop,user_xattr $calendar_dir/../calserver.img $calendar_dir
	else
		total_blocks=312500
		echo "===================================================================="
		echo ""
		echo "The installer has detected that the installation filesystem does not support extended attributes."
		echo "Extended Attribute support is required to run the calendar server."
		echo ""
		echo "The installer will create a disk image that supports extended attributes for you."
		echo "This partition can be increased or decreased in size at any time."
		echo ""
		echo "The default size for this partition is 5Gb."

		if [ $5 ]
			then
			echo "Please specify the size of the new partition in 16Kb blocks or [ENTER] to accept the default of 312500(5Gb):"
			read t1

			if [ -n "$t1" ]
				then
				total_blocks="$t1"
			fi

		fi

		echo "Creating device..."

		# main calendar directory
		mkdir -p ${calendar_dir} > /dev/null 2>&1

		dd if=/dev/zero of=$calendar_dir/../calserver.img bs=16k count=$total_blocks
		/sbin/mkfs.ext3 -F $calendar_dir/../calserver.img
		mount -o loop,user_xattr $calendar_dir/../calserver.img $calendar_dir
	fi
	echo "Done"
else
	echo "Ok"
fi

# ************* BUILD!!!! *************
# ************* make target directory structure *************
echo
echo "** Building **"
echo
echo "*********************************"
echo "* Please wait, this process may *"
echo "* take a while to complete.     *"
echo "*********************************"
echo
echo
echo "Logs of this process will be written to : ${logdir}"
echo

# reset the installation
sh reset_installation.sh

echo "Creating directory structure..."

# main calendar directory
if [ ! -d $calendar_dir ]
	then
	mkdir -p ${calendar_dir}
fi

server_path="$calendar_dir/server";
if [ ! -d $server_path ]
	then
	mkdir -p $server_path
fi

if [ ! -d $server_path/conf ]
	then
	mkdir -p $server_path/conf
fi

if [ ! -d ${server_path}/data ] 
	then
	mkdir ${server_path}/data
fi

if [ ! -d ${server_path}/twistedcaldav/atmail/data ]
	then
	mkdir -p ${server_path}/twistedcaldav/atmail/data
fi

if [ ! -d ${server_path}/logs ]
	then
	mkdir -p ${server_path}/logs
fi

# ************* compile deps *************
echo "Compiling dependancies..."
cd deps

jmake () {
  case "$(uname -s)" in
    Darwin|Linux)
      ncpu="$(getconf _NPROCESSORS_ONLN)";
      ;;
    FreeBSD)
      ncpu="$(sysctl hw.ncpu)";
      ncpu="${cpu##hw.ncpu: }";
      ;;
  esac;

  if [ -n "${ncpu:-}" ] && [[ "${ncpu}" =~ ^[0-9]+$ ]]; then
	echo "Making using ${ncpu} jobs.."
    make -j "${ncpu}" "$@";
  else
    make "$@";
  fi;
}

echo "Checking Python 2.6.2..."
if [ -f ${server_path}/python_installed ]
	then
	echo "Python 2.6.2 already compiled."
else
	echo "Uncompressing Python 2.6.2..."
	tar xzf Python-2.6.2.tgz
	cd Python-2.6.2
	echo "Configuring Python 2.6.2..."
	./configure > "${logdir}/python.2.6.2.configure.log" 2>&1
	echo "Building Python 2.6.2..."
	jmake ${verbose} > "${logdir}/python.2.6.2.build.log" 2>&1
	echo "Installing Python 2.6.2..."
	jmake install ${verbose} > "${logdir}/python.2.6.2.install.log" 2>&1
	cd ..
	touch ${server_path}/python_installed
fi

echo "Uncompressing configobj-4.6.0..."
tar xzf configobj-4.6.0.tar.gz
cd configobj-4.6.0
echo "Installing configobj-4.6.0..."
python setup.py install ${verbose} > "${logdir}/configobj-4.6.0.install.log" 2>&1
cd ..

echo "Uncompressing setuptools-0.6c9..."
tar xzf setuptools-0.6c9.tar.gz
cd setuptools-0.6c9
echo "Building setuptools-0.6c9..."
python setup.py build > "${logdir}/setuptools-0.6c9.build.log" 2>&1
echo "Installing setuptools-0.6c9..."
python setup.py install > "${logdir}/setuptools-0.6c9.install.log" 2>&1
cd ..

echo "Uncompressing MySQL-python-1.2.2..."
tar xzf MySQL-python-1.2.2.tar.gz
cd MySQL-python-1.2.2
echo "Building MySQL-python-1.2.2..."
python setup.py build > "${logdir}/MySQL-python-1.2.2.build.log" 2>&1
echo "Installing MySQL-python-1.2.2..."
python setup.py install > "${logdir}/MySQL-python-1.2.2.install.log" 2>&1
cd ..

# ************* prepare calendar installer *************
echo "Copying cached dependancies..."
cd ..
mkdir -p ./src/.dependencies
cp deps/* ./src/.dependencies
#mkdir -p ./vobject/
# cp deps/setuptools-0.6c11-py2.6.egg ./vobject/

# ************* compile calendar server *************
echo "Preparing to compile and install calendar server to ${server_path}..."
cd ./src

# ************* patch: svn checkouts will bork here *************
if [ -d ./.svn ]
	then
	mv ./.svn ./.svn.atmail
fi
if [ -d ../.svn ]
	then
	mv ../.svn ../.svn.atmail
fi

echo "Compiling calendar server..."
./run -s ${verbose} > "${logdir}/calendar.server.setup.log" 2>&1
echo "Finalising calendar server..."
./run -I ${server_path} ${verbose} > "${logdir}/calendar.server.install.log" 2>&1

# ************* Install calendar server to target directory *************
echo "Deploying calendar server to ${calendar_dir}..."
${install_file} run ${server_path}/

if [ -d ../Twisted ]
	then
	${install_folder} ../Twisted ${calendar_dir}/
fi

if [ -d ../vobject ]
	then
	${install_folder} ../vobject ${calendar_dir}/
fi
if [ -d ../libevent-1.4.8-stable ]
then
	${install_folder} ../libevent-1.4.8-stable ${calendar_dir}/
fi

if [ -d ../libevent-1.4.13-stable ]
	then
	${install_folder} ../libevent-1.4.13-stable ${calendar_dir}/
fi

if [ -d ../memcached-1.2.6 ]
then
	${install_folder} ../memcached-1.2.6 ${calendar_dir}/
fi

if [ -d ../memcached-1.4.5 ]
	then
	${install_folder} ../memcached-1.4.5 ${calendar_dir}/
fi

if [ -d ../pydirector-1.0.0 ]
	then
	${install_folder} ../pydirector-1.0.0 ${calendar_dir}/
fi

if [ -d ../Pyflakes ]
	then
	${install_folder} ../Pyflakes ${calendar_dir}/
fi

if [ -d ../PyKerberos ]
	then
	${install_folder} ../PyKerberos ${calendar_dir}/
fi

if [ -d ../pyOpenSSL-0.7 ]
then
	${install_folder} ../pyOpenSSL-0.7 ${calendar_dir}/
fi

if [ -d ../pyOpenSSL-0.10 ]
	then
	${install_folder} ../pyOpenSSL-0.10 ${calendar_dir}/
fi

if [ -d ../python-dateutil-1.4.1 ]
then
	${install_folder} ../python-dateutil-1.4.1 ${calendar_dir}/
fi

if [ -d ../python-dateutil-1.5 ]
	then
	${install_folder} ../python-dateutil-1.5 ${calendar_dir}/
fi

if [ -d ../PyXML-0.8.4 ]
	then
	${install_folder} ../PyXML-0.8.4 ${calendar_dir}/
fi

if [ -d ../xattr ]
	then
	${install_folder} ../xattr ${calendar_dir}/
fi

if [ -d ../zope.interface-3.3.0 ]
	then
	${install_folder} ../zope.interface-3.3.0 ${calendar_dir}/
fi

if [ -f ./conf/caldavd-dev.plist ]
then
	${install_file} ./conf/caldavd-dev.plist ${server_path}/conf/caldavd-dev.plist
fi

if [ -f ./conf/caldavd-atmail.plist ]
then
	${install_file} ./conf/caldavd-atmail.plist ${server_path}/conf/caldavd-dev.plist
fi

${install_folder} ./tw* ${server_path}/
${install_file} ./memcacheclient* ${server_path}/
${install_file} ./kqreactor.py ${server_path}/
${install_folder} ./calendarserver ${server_path}/
${install_folder} ./patches ${server_path}/
${install_file} ./patch_server.sh ${server_path}/
${install_file} ./config_server.sh ${server_path}/
${install_file} ./install_startup.php ${server_path}/
${install_file} ./../../scripts/atmailcalendarserver.sysvinit ${server_path}/atmailcalendarserver.sysvinit.template

# ************* patch: restore svn directory *************
if [ -d ./.svn.atmail ]
	then
	mv ./.svn.atmail ./.svn
fi
if [ -d ../.svn.atmail ]
	then
	mv ../.svn.atmail ../.svn
fi

# ************* apply mysql patch *************
echo "Patching and configuring calendar server..."
touch ${server_path}/atmail.ini
echo "[production]" > ${server_path}/atmail.ini
echo "dbconfig.path = $atmail_dir" >> ${server_path}/atmail.ini
chown atmail:atmail ${server_path}/atmail.ini

# ************* apply ownership *************
echo "Applying ownership to ${server_path}..."
cd $server_path
chown -R atmail:atmail ${server_path}/twistedcaldav/atmail
chown -R atmail:atmail ${server_path}/data
chown -R atmail:atmail ${server_path}/logs
chown -R atmail:atmail ${server_path}/../Twisted/twisted/plugins
mkdir -p /home/atmail
chown atmail:atmail /home/atmail
chown atmail:atmail ${server_path}/twisted/plugins
#chown atmail $atmail_dir -R

# ************* run port configurator and startup script installer *************
sh config_server.sh $calendar_port $calendar_port_ssl
sh patch_server.sh ${verbose}

if [ $3 ]
	then
	echo "Service startup configured"
else
	echo "Creating server startup file"
	php install_startup.php ${server_path} ${verbose}
fi


echo "Restarting Apache..."
if [ -f /usr/sbin/apachectl ]
	then
	/usr/sbin/apachectl restart
else
	if [ -f /usr/sbin/apache2ctl ]
		then
		/usr/sbin/apache2ctl restart
	else
		if [ -f /usr/local/apache2ctl ]
			then
			/usr/sbin/apache2ctl restart
		else
			if [ -f /usr/local/apache/logs/httpd.pid ]
				then
				kill -TERM `cat /usr/local/apache/logs/httpd.pid`
				/usr/sbin/httpd -k
			else
				echo "Unable to find apache, please manually restart"
			fi
		fi
	fi
fi

if [ -f $server_path/bin/caldavd ]
	then
	echo
	echo "Installed to:"
	echo $server_path
	echo
else
	echo "Calendar server failed to install."
fi
