#!/bin/sh
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
# 
#   http://www.apache.org/licenses/LICENSE-2.0
# 
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

#
# pxf-service	start/stop/initialize/status the PXF instance
#


if [ -z $PXF_HOME ]; then
    env_script=/etc/pxf/conf/pxf-env.sh
else
    env_script=$PXF_HOME/conf/pxf-env.sh
fi

# load pxf-env.sh script
if [ ! -f $env_script ]; then
	echo WARNING: failed to find $env_script
else
	source $env_script
fi

pxf_user=$PXF_USER
instance_port=$PXF_PORT
instance_name=pxf-service

if [ -z $PXF_HOME ]; then
    # RPM based setup
    pxf_root=/usr/lib/pxf
    tomcat_root=/opt/apache-tomcat
    tomcat_templates=/opt/pxf/tomcat-templates
    instance_root=/var/pxf
    instance_owner=$pxf_user:$pxf_user
else
    # OSS/Source code based setup
    pxf_root=$PXF_HOME/lib
    tomcat_root=$PXF_HOME/apache-tomcat
    tomcat_templates=$PXF_HOME/tomcat-templates
    instance_root=$PXF_HOME
    instance_owner=$pxf_user
fi

curl=`which curl`


# validate JAVA_HOME
if [ ! -x $JAVA_HOME/bin/java ]; then
	echo ERROR: \$JAVA_HOME is invalid
	exit 1
fi

#
# createInstance creates a tomcat instance 
# configuration files 
#
function createInstance()
{
	mkdir -p $instance_root 
	mkdir -p $instance_root/$instance_name 
	cp -r $tomcat_root/* $instance_root/$instance_name/.

	if [ $? -gt 0 ]; then
		echo ERROR: instance creation failed
		return 1
	fi

	chown -R $instance_owner $instance_root
	chmod 700 $instance_root/$instance_name
	return 0
}

#
# configureInstance configures the tomcat instance
# based on pre-configured template files.
#
# specifically:
#	support up to 30,000 header fields
#	support up to 1MB size header
#	change connection timeout to 60 seconds
#	set port to 51200
#
function configureInstance()
{
	# copy configuration files into instance
	cp $tomcat_templates/bin/setenv.sh $instance_root/$instance_name/bin/setenv.sh
	cp $tomcat_templates/conf/catalina.properties $instance_root/$instance_name/conf/.
	cp $tomcat_templates/conf/server.xml $instance_root/$instance_name/conf/.
	cp $tomcat_templates/conf/web.xml $instance_root/$instance_name/conf/.
	
	# set port
	catalinaProperties=$instance_root/$instance_name/conf/catalina.properties
	cat $catalinaProperties | \
	sed "s|^[[:blank:]]*connector.http.port=.*$|connector.http.port=$instance_port|g" \
	> ${catalinaProperties}.tmp

	rm $catalinaProperties
	mv ${catalinaProperties}.tmp $catalinaProperties

	# set pid
	catalinaEnv=$instance_root/$instance_name/bin/setenv.sh
	cat $catalinaEnv | \
	sed -e "s|^[[:blank:]]*CATALINA_PID=.*$|CATALINA_PID=$PXF_RUNDIR/catalina.pid|g" \
	> ${catalinaEnv}.tmp
	rm $catalinaEnv
	mv ${catalinaEnv}.tmp $catalinaEnv

	# set log directories
	catalinaLog=$instance_root/$instance_name/conf/logging.properties
	cat $catalinaLog | \
	sed "s|juli.FileHandler.directory\s*=.*$|juli.FileHandler.directory = $PXF_LOGDIR|g" \
	> ${catalinaLog}.tmp
	rm $catalinaLog
	mv ${catalinaLog}.tmp $catalinaLog

	return 0
}

#
# deployWebapp adds the pxf-webapp to the new instance's webapps folder
# and the custom loader to the instance's lib directory
#
function deployWebapp()
{
	cp $pxf_root/pxf.war $instance_root/$instance_name/webapps/ || return 1
	cp $pxf_root/pxf-service-*[0-9].jar $instance_root/$instance_name/lib/ || return 1

	return 0
}

#
# waitForTomcat waits for tomcat to finish loading
# for given attempts number.
#
function waitForTomcat()
{
	attempts=0
	max_attempts=$1 # number of attempts to connect 
	sleep_time=1 # sleep 1 second between attempts
	
	# wait until tomcat is up:
	echo Checking if tomcat is up and running...
	until [[ "`curl --silent --connect-timeout 1 -I http://localhost:${instance_port} | grep 'Coyote'`" != "" ]];
	do
		let attempts=attempts+1
		if [[ "$attempts" -eq "$max_attempts" ]]; then
			echo ERROR: PXF is down - tomcat is not running
			return 1
		fi
		echo "tomcat not responding, re-trying after ${sleep_time} second (attempt number ${attempts})"
		sleep $sleep_time
	done

	return 0
}

#
# checkWebapp checks if tomcat is up for $1 attempts and then
# verifies PXF webapp is functional
#
function checkWebapp()
{
	waitForTomcat $1 || return 1
	
	echo Checking if PXF webapp is up and running...
	curlResponse=$($curl -s "http://localhost:${instance_port}/pxf/v0")
	expectedResponse="Wrong version v0, supported version is v[0-9]+"
	
	if [[ $curlResponse =~ $expectedResponse ]]; then
		echo PXF webapp is up
		return 0
	fi
	
	echo ERROR: PXF webapp is inaccessible but tomcat is up. Check logs for more information
	return 1
}

# instanceExists returns 0 when the instance exists
# non zero otherwise
function instanceExists()
{
	if [ ! -d "$instance_root/$instance_name" ]; then
		return 1
	fi

	$instance_root/$instance_name/bin/catalina.sh version > /dev/null 2>&1
	return $?
}

# doInit handles the init command
function doInit()
{
	instanceExists
	if [ $? -eq 0 ]; then
		echo WARNING: instance already exists in $instance_root, nothing to do...
		return 0
	fi

    createInstance || return 1
	configureInstance || return 1
	deployWebapp || return 1
}

#
# patchWebapp patches the webapp config files
# patch applied only if PXF_HOME is defined
#
function patchWebapp()
{
    if [ -z $PXF_HOME ]; then
        # webapp doesn't require patch
        return 0
    fi
    pushd $instance_root/$instance_name/webapps || return 1
    rm -rf pxf
    mkdir pxf
    cd pxf
    unzip -q ../pxf.war
    popd

    context_file=$instance_root/$instance_name/webapps/pxf/META-INF/context.xml
    cat $context_file | \
    sed  -e "s:classpathFiles=\"[a-zA-Z0-9\/\;.-]*\":classpathFiles=\"$PXF_HOME\/conf\/pxf-private.classpath\":" \
    -e "s:secondaryClasspathFiles=\"[a-zA-Z0-9\/\;.-]*\":secondaryClasspathFiles=\"$PXF_HOME\/conf\/pxf-public.classpath\":" > context.xml.tmp
    mv context.xml.tmp $context_file

    web_file=$instance_root/$instance_name/webapps/pxf/WEB-INF/web.xml
    cat $web_file | \
    sed "s:<param-value>.*pxf-log4j.properties<\/param-value>:<param-value>$PXF_HOME\/conf\/pxf-log4j.properties<\/param-value>:" > web.xml.tmp
    mv web.xml.tmp $web_file
}

function commandWebapp()
{
    command=$1
    pushd $instance_root
    su $pxf_user -c "$instance_root/$instance_name/bin/catalina.sh $command"
    if [ $? -ne 0 ]; then
        return 1
    fi
    popd
}

# 
# doStart handles start command
# command is executed as the user $pxf_user
#
# after start, uses checkWebapp to verify the PXF webapp was loaded
# successfully
#
function doStart()
{
	instanceExists
	if [ $? -ne 0 ]; then
		echo ERROR: cant find PXF instance, maybe call init?
		return 1
	fi
	patchWebapp || return 1
	commandWebapp start || return 1
	checkWebapp 300 || return 1
}

#
# doStart handles stop command
# command is executed as the user $pxf_user
#
#
function doStop()
{
    instanceExists
    if [ $? -ne 0 ]; then
        echo "ERROR: can't find PXF instance, maybe call init?"
        return 1
    fi
    commandWebapp stop || return 1
}

function doStatus()
{
	checkWebapp 1 || return 1
}

command=$1

case "$command" in
	"init" )
		doInit
		;;
	"start" )
		doStart
		;;
	"stop" )
		doStop
		;;
	"restart" )
		doStop
		sleep 1s
		doStart
		;;
	"status" )
		doStatus
		;;
	* )
		echo $"Usage: $0 {start|stop|restart|init|status}"
		exit 2
		;;
esac

exit $?
