#!/bin/bash

# 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.

function getInstallProperty() {
    local propertyName=$1
    local propertyValue=""

    for file in "${COMPONENT_INSTALL_ARGS}" "${INSTALL_ARGS}"
    do
        if [ -f "${file}" ]
        then
            propertyValue=`grep "^${propertyName}[ \t]*=" ${file} | awk -F= '{  sub("^[ \t]*", "", $2); sub("[ \t]*$", "", $2); print $2 }'`
            if [ "${propertyValue}" != "" ]
            then
                break
            fi
        fi
    done

    echo ${propertyValue}
}

#
# Base env variable for Ranger related files/directories
#
PROJ_NAME=ranger
BASE_CONF_DIR=/etc/${PROJ_NAME}

#
# The script should be run by "root" user
#

if [ ! -w /etc/passwd ]
then
    echo "ERROR: $0 script should be run as root."
    exit 1
fi

#Check for JAVA_HOME
if [ "${JAVA_HOME}" == "" ]
then
    echo "ERROR: JAVA_HOME environment property not defined, aborting installation."
    exit 1
fi

#
# Identify the component, action from the script file
#

basedir=`dirname $0`
if [ "${basedir}" = "." ]
then
    basedir=`pwd`
elif [ "${basedir}" = ".." ]
then
    basedir=`(cd .. ;pwd)`
fi

#
# As this script is common to all component, find the component name based on the script-name
#

COMPONENT_NAME=`basename $0 | cut -d. -f1 | sed -e 's:^disable-::' | sed -e 's:^enable-::'`

echo "${COMPONENT_NAME}" | grep 'plugin' > /dev/null 2>&1

if [ $? -ne 0 ]
then
	echo "$0 : is not applicable for component [${COMPONENT_NAME}]. It is applicable only for ranger plugin component; Exiting ..."
	exit 0 
fi

HCOMPONENT_NAME=`echo ${COMPONENT_NAME} | sed -e 's:-plugin::'`

CFG_OWNER_INF="${HCOMPONENT_NAME}:${HCOMPONENT_NAME}"

if [ "${HCOMPONENT_NAME}" = "hdfs" ]
then
	HCOMPONENT_NAME="hadoop"
fi

#
# Based on script name, identify if the action is enabled or disabled
#

basename $0 | cut -d. -f1 | grep '^enable-' > /dev/null 2>&1

if [ $? -eq 0 ]
then
	action=enable
else
	action=disable
fi


#
# environment variables for enable|disable scripts 
#

PROJ_INSTALL_DIR=`(cd ${basedir} ; pwd)`
SET_ENV_SCRIPT_NAME=set-${COMPONENT_NAME}-env.sh
SET_ENV_SCRIPT_TEMPLATE=${PROJ_INSTALL_DIR}/install/conf.templates/enable/${SET_ENV_SCRIPT_NAME}
DEFAULT_XML_CONFIG=${PROJ_INSTALL_DIR}/install/conf.templates/default/configuration.xml
PROJ_LIB_DIR=${PROJ_INSTALL_DIR}/lib
PROJ_INSTALL_LIB_DIR="${PROJ_INSTALL_DIR}/install/lib"
INSTALL_ARGS="${PROJ_INSTALL_DIR}/install.properties"
COMPONENT_INSTALL_ARGS="${PROJ_INSTALL_DIR}/${COMPONENT_NAME}-install.properties"
JAVA=$JAVA_HOME/bin/java

PLUGIN_DEPENDENT_LIB_DIR=lib/"${PROJ_NAME}-${COMPONENT_NAME}-impl"
PROJ_LIB_PLUGIN_DIR=${PROJ_INSTALL_DIR}/${PLUGIN_DEPENDENT_LIB_DIR}

HCOMPONENT_INSTALL_DIR_NAME=$(getInstallProperty 'COMPONENT_INSTALL_DIR_NAME')


CUSTOM_USER=$(getInstallProperty 'CUSTOM_USER')
CUSTOM_USER=${CUSTOM_USER// }

CUSTOM_GROUP=$(getInstallProperty 'CUSTOM_GROUP')
CUSTOM_GROUP=${CUSTOM_GROUP// }



if [ ! -z "${CUSTOM_USER}" ] && [ ! -z "${CUSTOM_GROUP}" ]
then
  echo "Custom user and group is available, using custom user and group."
  CFG_OWNER_INF="${CUSTOM_USER}:${CUSTOM_GROUP}"
elif [ ! -z "${CUSTOM_USER}" ] && [ -z "${CUSTOM_GROUP}" ]
then
  echo "Custom user is available, using custom user and default group."
  CFG_OWNER_INF="${CUSTOM_USER}:${HCOMPONENT_NAME}"
elif [ -z  "${CUSTOM_USER}" ] && [ ! -z  "${CUSTOM_GROUP}" ]
then
  echo "Custom group is available, using default user and custom group."
  CFG_OWNER_INF="${HCOMPONENT_NAME}:${CUSTOM_GROUP}"
else
  echo "Custom user and group are not available, using default user and group."
  CFG_OWNER_INF="${HCOMPONENT_NAME}:${HCOMPONENT_NAME}"
fi

if [ "${HCOMPONENT_INSTALL_DIR_NAME}" = "" ]
then
	HCOMPONENT_INSTALL_DIR_NAME=${HCOMPONENT_NAME}
fi

firstletter=${HCOMPONENT_INSTALL_DIR_NAME:0:1}
if [ "$firstletter" = "/" ]; then
    hdir=${HCOMPONENT_INSTALL_DIR_NAME}
else
    hdir=${PROJ_INSTALL_DIR}/../${HCOMPONENT_INSTALL_DIR_NAME}
fi

#
# TEST - START
#
if [ ! -d ${hdir} ]
then
	mkdir -p ${hdir}
fi
#
# TEST - END
#
HCOMPONENT_INSTALL_DIR=`(cd ${hdir} ; pwd)`
HCOMPONENT_LIB_DIR=${HCOMPONENT_INSTALL_DIR}/lib
if [ "${HCOMPONENT_NAME}" = "knox" ]; then
	HCOMPONENT_LIB_DIR=${HCOMPONENT_INSTALL_DIR}/ext
elif [ "${HCOMPONENT_NAME}" = "solr" ]; then
    HCOMPONENT_LIB_DIR=${HCOMPONENT_INSTALL_DIR}/solr-webapp/webapp/WEB-INF/lib
elif [ "${HCOMPONENT_NAME}" = "kafka" ]; then
    HCOMPONENT_LIB_DIR=${HCOMPONENT_INSTALL_DIR}/libs
elif [ "${HCOMPONENT_NAME}" = "storm" ]; then
    HCOMPONENT_LIB_DIR=${HCOMPONENT_INSTALL_DIR}/extlib-daemon
elif [ "${HCOMPONENT_NAME}" = "atlas" ]; then
    HCOMPONENT_LIB_DIR=${HCOMPONENT_INSTALL_DIR}/libext
fi

HCOMPONENT_CONF_DIR=${HCOMPONENT_INSTALL_DIR}/conf
if [ "${HCOMPONENT_NAME}" = "solr" ]; then
    HCOMPONENT_CONF_DIR=${HCOMPONENT_INSTALL_DIR}/solr-webapp/webapp/WEB-INF/classes
    if [ ! -d $HCOMPONENT_CONF_DIR ]; then	
	install_owner=`ls -ld | cut -f 3 -d " "`
	echo "INFO: Creating $HCOMPONENT_CONF_DIR" 
	mkdir -p $HCOMPONENT_CONF_DIR
	echo "INFO: Changing ownership of  $HCOMPONENT_CONF_DIR to $install_owner" 
	chown $install_owner:$install_owner $HCOMPONENT_CONF_DIR
    fi    
elif [ "${HCOMPONENT_NAME}" = "kafka" ]; then
    HCOMPONENT_CONF_DIR=${HCOMPONENT_INSTALL_DIR}/config
fi

HCOMPONENT_ARCHIVE_CONF_DIR=${HCOMPONENT_CONF_DIR}/.archive
SET_ENV_SCRIPT=${HCOMPONENT_CONF_DIR}/${SET_ENV_SCRIPT_NAME}


if [ ! -d "${HCOMPONENT_INSTALL_DIR}" ]
then
	echo "ERROR: Unable to find the install directory of component [${HCOMPONENT_NAME}]; dir [${HCOMPONENT_INSTALL_DIR}] not found."
	echo "Exiting installation."
	exit 1
fi

if [ ! -d "${HCOMPONENT_CONF_DIR}" ]
then
	echo "ERROR: Unable to find the conf directory of component [${HCOMPONENT_NAME}]; dir [${HCOMPONENT_CONF_DIR}] not found."
	echo "Exiting installation."
	exit 1
fi

if [ ! -d "${HCOMPONENT_LIB_DIR}" ]
then
	echo "ERROR: Unable to find the lib directory of component [${HCOMPONENT_NAME}];  dir [${HCOMPONENT_LIB_DIR}] not found."
	echo "Exiting installation."
	exit 1
fi

ambari_hive_install="N"
if  [ "${HCOMPONENT_NAME}" = "hive" ]
then
	HCOMPONENT_CONF_SERVER_DIR="${HCOMPONENT_CONF_DIR}"/conf.server
	if [ -d "${HCOMPONENT_CONF_SERVER_DIR}" ]
	then 
		ambari_hive_install="Y"
	fi
fi

#
# Common functions used by all enable/disable scripts
#

log() {
	echo "+ `date` : $*"
}


create_jceks() {

	alias=$1
	pass=$2
	jceksFile=$3

	if [ -f "${jceksFile}" ]
	then
		jcebdir=`dirname ${jceksFile}`
		jcebname=`basename ${jceksFile}`
		archive_jce=${jcebdir}/.${jcebname}.`date '+%Y%m%d%H%M%S'`
		log "Saving current JCE file: ${jceksFile} to ${archive_jce} ..."
		cp ${jceksFile} ${archive_jce}
	fi

	tempFile=/tmp/jce.$$.out

    $JAVA_HOME/bin/java -cp ":${PROJ_INSTALL_LIB_DIR}/*:" org.apache.ranger.credentialapi.buildks create "${alias}" -value "${pass}" -provider "jceks://file${jceksFile}" > ${tempFile} 2>&1

	if [ $? -ne 0 ]
	then
		echo "Unable to store password in non-plain text format. Error: [`cat ${tempFile}`]"
		echo "Exiting plugin installation"
		rm -f ${tempFile}
		exit 0
	fi
	
	rm -f ${tempFile}
}

log "${HCOMPONENT_NAME}: lib folder=$HCOMPONENT_LIB_DIR conf folder=$HCOMPONENT_CONF_DIR"

#
# If there is a set-ranger-${COMPONENT}-env.sh, install it
#
dt=`date '+%Y%m%d-%H%M%S'`

if [ -f "${SET_ENV_SCRIPT_TEMPLATE}" ]
then
	#
	# If the setenv script already exists, move it to the archive folder
	#
	if [ -f "${SET_ENV_SCRIPT}" ]
	then
		if [ ! -d "${HCOMPONENT_ARCHIVE_CONF_DIR}" ]
		then
			mkdir -p ${HCOMPONENT_ARCHIVE_CONF_DIR}
		fi
		log "Saving current ${SET_ENV_SCRIPT_NAME} to ${HCOMPONENT_ARCHIVE_CONF_DIR} ..."
		mv ${SET_ENV_SCRIPT} ${HCOMPONENT_ARCHIVE_CONF_DIR}/${SET_ENV_SCRIPT_NAME}.${dt}
	fi
	
	if [ "${action}" = "enable" ]
	then

		cp ${SET_ENV_SCRIPT_TEMPLATE} ${SET_ENV_SCRIPT}

		DEST_SCRIPT_FILE=${HCOMPONENT_INSTALL_DIR}/libexec/${HCOMPONENT_NAME}-config.sh

		DEST_SCRIPT_ARCHIVE_FILE=${HCOMPONENT_INSTALL_DIR}/libexec/.${HCOMPONENT_NAME}-config.sh.${dt}

		if [ -f "${DEST_SCRIPT_FILE}" ]
		then

			log "Saving current ${DEST_SCRIPT_FILE} to ${DEST_SCRIPT_ARCHIVE_FILE} ..."

			cp ${DEST_SCRIPT_FILE} ${DEST_SCRIPT_ARCHIVE_FILE}

			grep 'xasecure-.*-env.sh' ${DEST_SCRIPT_FILE} > /dev/null 2>&1
			if [ $? -eq 0 ]
			then
				ts=`date '+%Y%m%d%H%M%S'`
				grep -v 'xasecure-.*-env.sh' ${DEST_SCRIPT_FILE} > ${DEST_SCRIPT_FILE}.${ts} 
				if [ $? -eq 0 ]
				then
					log "Removing old reference to xasecure setenv source ..."
					cat ${DEST_SCRIPT_FILE}.${ts} > ${DEST_SCRIPT_FILE}
					rm -f ${DEST_SCRIPT_FILE}.${ts}
				fi
			fi

			grep "[ \t]*.[ \t]*${SET_ENV_SCRIPT}" ${DEST_SCRIPT_FILE} > /dev/null
			if [ $? -ne 0 ]
			then
				log "Appending sourcing script, ${SET_ENV_SCRIPT_NAME} in the file: ${DEST_SCRIPT_FILE} "
				cat >> ${DEST_SCRIPT_FILE} <<!
if [ -f ${SET_ENV_SCRIPT} ]
then
	.  ${SET_ENV_SCRIPT}
fi
!
			else
				log "INFO: ${DEST_SCRIPT_FILE} is being sourced from file: ${HCOMPONENT_CONF_DIR}/${HCOMPONENT_NAME}-env.sh "
			fi
		fi
	fi
fi

#
# Run, the enable|disable ${COMPONENT} configurations 
#

if [ -d "${PROJ_INSTALL_DIR}/install/conf.templates/${action}" ]
then
	INSTALL_CP="${PROJ_INSTALL_LIB_DIR}/*" 
	if [ "${action}" = "enable" ]
	then
		echo "<ranger>\n<enabled>`date`</enabled>\n</ranger>" > ${HCOMPONENT_CONF_DIR}/ranger-security.xml
		chown ${CFG_OWNER_INF} ${HCOMPONENT_CONF_DIR}/ranger-security.xml
		chmod a+r ${HCOMPONENT_CONF_DIR}/ranger-security.xml
		for cf in ${PROJ_INSTALL_DIR}/install/conf.templates/${action}/*.xml
		do
			cfb=`basename ${cf}`
			if [ -f "${HCOMPONENT_CONF_DIR}/${cfb}" ]
			then
				log "Saving ${HCOMPONENT_CONF_DIR}/${cfb} to ${HCOMPONENT_CONF_DIR}/.${cfb}.${dt} ..."
				cp ${HCOMPONENT_CONF_DIR}/${cfb} ${HCOMPONENT_CONF_DIR}/.${cfb}.${dt}
			fi
			cp ${cf} ${HCOMPONENT_CONF_DIR}/
			chown ${CFG_OWNER_INF} ${HCOMPONENT_CONF_DIR}/${cfb}
			chmod a+r ${HCOMPONENT_CONF_DIR}/${cfb}
		done
    else
		if [ -f ${HCOMPONENT_CONF_DIR}/ranger-security.xml ]
		then
			mv ${HCOMPONENT_CONF_DIR}/ranger-security.xml ${HCOMPONENT_CONF_DIR}/.ranger-security.xml.`date '+%Y%m%d%H%M%S'`
		fi
	fi

	#
	# Ensure that POLICY_CACHE_FILE_PATH is accessible
	#
	REPO_NAME=$(getInstallProperty 'REPOSITORY_NAME')
	export POLICY_CACHE_FILE_PATH=/etc/${PROJ_NAME}/${REPO_NAME}/policycache
	export CREDENTIAL_PROVIDER_FILE=/etc/${PROJ_NAME}/${REPO_NAME}/cred.jceks
	if [ ! -d ${POLICY_CACHE_FILE_PATH} ]
	then
		mkdir -p ${POLICY_CACHE_FILE_PATH}
	fi
	chmod a+rx /etc/${PROJ_NAME}
	chmod a+rx /etc/${PROJ_NAME}/${REPO_NAME}
	chmod a+rx ${POLICY_CACHE_FILE_PATH}
	chown -R ${CFG_OWNER_INF} /etc/${PROJ_NAME}/${REPO_NAME}
	

	#
	# We need to do the AUDIT JDBC url 
	#
db_flavor=''
db_flavor=`echo $(getInstallProperty 'XAAUDIT.DB.FLAVOUR') | tr '[:lower:]' '[:upper:]'`
if [ "${db_flavor}" != "" ]
then
    audit_db_hostname=$(getInstallProperty 'XAAUDIT.DB.HOSTNAME')
    audit_db_name=$(getInstallProperty 'XAAUDIT.DB.DATABASE_NAME')

	if [ "${db_flavor}" = "MYSQL" ]
	then
    	export XAAUDIT_DB_JDBC_URL="jdbc:mysql://${audit_db_hostname}/${audit_db_name}"
    	export XAAUDIT_DB_JDBC_DRIVER="com.mysql.jdbc.Driver"
	elif [ "${db_flavor}" = "ORACLE" ]
	then
		count=$(grep -o ":" <<< "$audit_db_hostname" | wc -l)
		#if [[ ${count} -eq 2 ]] ; then
		if [ ${count} -eq 2 ] || [ ${count} -eq 0 ]; then
			#jdbc:oracle:thin:@[HOST][:PORT]:SID or #jdbc:oracle:thin:@GL
			newPropertyValue="jdbc:oracle:thin:@${audit_db_hostname}"
		else
			#jdbc:oracle:thin:@//[HOST][:PORT]/SERVICE
			newPropertyValue="jdbc:oracle:thin:@//${audit_db_hostname}"
		fi
		export XAAUDIT_DB_JDBC_URL=${newPropertyValue}
    	export XAAUDIT_DB_JDBC_DRIVER="oracle.jdbc.OracleDriver"
    elif [ "${db_flavor}" = "POSTGRES" ]
	then
		export XAAUDIT_DB_JDBC_URL="jdbc:postgresql://${audit_db_hostname}/${audit_db_name}"
		export XAAUDIT_DB_JDBC_DRIVER="org.postgresql.Driver"
	elif [ "${db_flavor}" = "MSSQL" ]
	then
		export XAAUDIT_DB_JDBC_URL="jdbc:sqlserver://${audit_db_hostname};databaseName=${audit_db_name}"
		export XAAUDIT_DB_JDBC_DRIVER="com.microsoft.sqlserver.jdbc.SQLServerDriver"
	elif [ "${db_flavor}" = "SQLA" ]
	then
		export XAAUDIT_DB_JDBC_URL="jdbc:sqlanywhere:database=${audit_db_name};host=${audit_db_hostname}"
		export XAAUDIT_DB_JDBC_DRIVER="sap.jdbc4.sqlanywhere.IDriver"
	else
        echo "Audit is not specified with a valid db_flavor: [${db_flavor}]. Ignoring audit ..."
        export XAAUDIT_DB_JDBC_URL="jdbc:${db_flavor}://${audit_db_hostname}/${audit_db_name}"
        export XAAUDIT_DB_JDBC_DRIVER="com.unknown.driver.${db_flavor}"
	fi
fi


	for f in ${PROJ_INSTALL_DIR}/install/conf.templates/${action}/*.cfg
	do
		if [ -f "${f}" ]
		then
			fn=`basename $f`
        	orgfn=`echo $fn | sed -e 's:-changes.cfg:.xml:'`
        	fullpathorgfn="${HCOMPONENT_CONF_DIR}/${orgfn}"
        	if [ ! -f ${fullpathorgfn} ]
        	then
				if [ -f ${DEFAULT_XML_CONFIG} ]
				then
					log "Creating default file from [${DEFAULT_XML_CONFIG}] for [${fullpathorgfn}] .."
					cp ${DEFAULT_XML_CONFIG} ${fullpathorgfn}
				 	chown ${CFG_OWNER_INF} ${fullpathorgfn}	
				else
        			echo "ERROR: Unable to find ${fullpathorgfn}"
        			exit 1
				fi
        	fi
			archivefn="${HCOMPONENT_CONF_DIR}/.${orgfn}.${dt}"
        	newfn="${HCOMPONENT_CONF_DIR}/.${orgfn}-new.${dt}"
			log "Saving current config file: ${fullpathorgfn} to ${archivefn} ..."
            cp ${fullpathorgfn} ${archivefn}
			if [ $? -eq 0 ]
			then
				${JAVA} -cp "${INSTALL_CP}" org.apache.ranger.utils.install.XmlConfigChanger -i ${archivefn} -o ${newfn} -c ${f} -p  ${INSTALL_ARGS}
				if [ $? -eq 0 ]
                then
                	diff -w ${newfn} ${fullpathorgfn} > /dev/null 2>&1
                    if [ $? -ne 0 ]
                    then
                    	cat ${newfn} > ${fullpathorgfn}
                    fi
                    
                    # For Ambari install copy the .xml to conf.server also
					if [ "${ambari_hive_install}" = "Y" ]
					then
					    fullpathorgHS2fn="${HCOMPONENT_CONF_SERVER_DIR}/${orgfn}"
					    archiveHS2fn="${HCOMPONENT_CONF_SERVER_DIR}/.${orgfn}.${dt}"
        				newHS2fn="${HCOMPONENT_CONF_SERVER_DIR}/.${orgfn}-new.${dt}"
						log "Saving current conf.server file: ${fullpathorgHS2fn} to ${archiveHS2fn} ..."
						if [ -f ${fullpathorgHS2fn} ]
						then 
            				cp ${fullpathorgHS2fn} ${archiveHS2fn}
            			fi
						cp ${fullpathorgfn} ${HCOMPONENT_CONF_SERVER_DIR}/${orgfn}
						chown ${CFG_OWNER_INF} ${HCOMPONENT_CONF_SERVER_DIR}/${orgfn}
					fi
					
               	else
				    echo "ERROR: Unable to make changes to config. file: ${fullpathorgfn}"
                    echo "exiting ...."
                    exit 1
				fi
			else
				echo "ERROR: Unable to save config. file: ${fullpathorgfn}  to ${archivefn}"
                echo "exiting ...."
                exit 1
			fi
		fi
	done
	if [ "${HCOMPONENT_NAME}" = "hbase" ] || [ "${HCOMPONENT_NAME}" = "storm" ];
	then
		chmod 644 ${HCOMPONENT_CONF_DIR}/*
	fi
fi

#
# Create library link
#

if [ "${action}" = "enable" ]
then

	#if [ -d "${PROJ_LIB_DIR}" ]
	#then
		dt=`date '+%Y%m%d%H%M%S'`
        for f in ${PROJ_LIB_DIR}/*
            do
               if [ -f "${f}" ] || [ -d "${f}" ]
               then
                   bn=`basename $f`
                   if [ -f ${HCOMPONENT_LIB_DIR}/${bn} ] || [  -d ${HCOMPONENT_LIB_DIR}/${bn} ]
                   then
                       log "Saving lib file: ${HCOMPONENT_LIB_DIR}/${bn} to ${HCOMPONENT_LIB_DIR}/.${bn}.${dt} ..."
                       mv ${HCOMPONENT_LIB_DIR}/${bn} ${HCOMPONENT_LIB_DIR}/.${bn}.${dt}
                   fi
                   if [ ! -f ${HCOMPONENT_LIB_DIR}/${bn} ] && [ ! -d  ${HCOMPONENT_LIB_DIR}/${bn} ]
                   then
                       ln -s ${f} ${HCOMPONENT_LIB_DIR}/${bn}
                   fi
                fi
        done
		# ADD SQL CONNECTOR JAR TO PLUGIN DEPENDENCY JAR FOLDER
		dbJar=$(getInstallProperty 'SQL_CONNECTOR_JAR')
		if [ -f "${dbJar}" ]
		then	
			bn=`basename ${dbJar}`
			if [ -f ${PROJ_LIB_PLUGIN_DIR}/${bn} ]
			then
			 	rm ${PROJ_LIB_PLUGIN_DIR}/${bn} 
			fi
			if [ ! -f ${PROJ_LIB_PLUGIN_DIR}/${bn} ]
			then
			    ln -s ${dbJar} ${PROJ_LIB_PLUGIN_DIR}/${bn}
			fi
		fi

	#fi

	#
	# Encrypt the password and keep it secure in Credential Provider API
	#
	
	CredFile=${CREDENTIAL_PROVIDER_FILE}

	if ! [ `echo ${CredFile} | grep '^/.*'` ]
	then
  	echo "ERROR:Please enter the Credential File Store with proper file path"
  	exit 1
	fi
	
	pardir=`dirname ${CredFile}`
	
	if [ ! -d "${pardir}" ]
	then
		mkdir -p "${pardir}" 
	
		if [ $? -ne 0 ]
		then
    		echo "ERROR: Unable to create credential store file path"
			exit 1
		fi
		chmod a+rx "${pardir}"
	fi

	#
	# Generate Credential Provider file and Credential for Audit DB access.
	#
	
	
	auditCredAlias="auditDBCred"
	
	auditdbCred=$(getInstallProperty 'XAAUDIT.DB.PASSWORD')
	
	if [ "${auditdbCred}" != "" ]; then
		create_jceks "${auditCredAlias}"  "${auditdbCred}"  "${CredFile}"
	fi
	
	
	#
	# Generate Credential Provider file and Credential for SSL KEYSTORE AND TRUSTSTORE
	#
	
	
	sslkeystoreAlias="sslKeyStore"
	
	sslkeystoreCred=$(getInstallProperty 'SSL_KEYSTORE_PASSWORD')
	
	create_jceks "${sslkeystoreAlias}" "${sslkeystoreCred}" "${CredFile}"
	
	
	ssltruststoreAlias="sslTrustStore"
	
	ssltruststoreCred=$(getInstallProperty 'SSL_TRUSTSTORE_PASSWORD')
	
	create_jceks "${ssltruststoreAlias}" "${ssltruststoreCred}" "${CredFile}"
	
	chown ${CFG_OWNER_INF} ${CredFile}
	#
	# To allow all users in the server (where Hive CLI and HBase CLI is used),
	# user needs to have read access for the credential file.
	#
	chmod a+r ${CredFile} 
	
fi

#
# Knox specific configuration
#
#

if [ "${HCOMPONENT_NAME}" = "knox" ]
then
	if [ "${action}" = "enable" ]
	then
		authFrom="AclsAuthz"
		authTo="XASecurePDPKnox"
	else
		authTo="AclsAuthz"
		authFrom="XASecurePDPKnox"
	fi

	dt=`date '+%Y%m%d%H%M%S'`
	for fn in `ls ${HCOMPONENT_CONF_DIR}/topologies/*.xml 2> /dev/null`
	do
  		if [ -f "${fn}" ]
  		then
    		dn=`dirname ${fn}`
    		bn=`basename ${fn}`
    		bf=${dn}/.${bn}.${dt}
    		echo "backup of ${fn} to ${bf} ..."
    		cp ${fn} ${bf}
    		echo "Updating topology file: [${fn}] ... " 
    		cat ${fn} | sed -e "s-<name>${authFrom}</name>-<name>${authTo}</name>-" > ${fn}.${dt}.new
    		if [ $? -eq 0 ]
    		then
        		cat ${fn}.${dt}.new > ${fn}
        		rm ${fn}.${dt}.new
    		fi 
  		fi
	done
fi

if [ "${HCOMPONENT_NAME}" = "storm" ]
then
	CFG_FILE=${HCOMPONENT_CONF_DIR}/storm.yaml
	ARCHIVE_FILE=${HCOMPONENT_CONF_DIR}/.storm.yaml.`date '+%Y%m%d%H%M%S'`

	if [ -f "${CFG_FILE}" ]
	then
		cp ${CFG_FILE}  ${ARCHIVE_FILE}

    	if [ "${action}" = "enable" ]
    	then
			awk -F: 'BEGIN {
    			configured = 0 ;
			}
			{
    			if ($1 == "nimbus.authorizer") {
        			if ($2 ~ /^[ \t]*"org.apache.ranger.authorization.storm.authorizer.RangerStormAuthorizer"[ \t]*$/) {
            			configured = 1 ;
            			printf("%s\n",$0) ;
        			}
        			else {
            			printf("#%s\n",$0);
            			printf("nimbus.authorizer: \"org.apache.ranger.authorization.storm.authorizer.RangerStormAuthorizer\"\n") ;
            			configured = 1 ;
        			}
    			}
    			else {
        			printf("%s\n",$0) ;
    			}
			}
			END {
    			if (configured == 0) {
        			printf("nimbus.authorizer: \"org.apache.ranger.authorization.storm.authorizer.RangerStormAuthorizer\"\n") ;
    			}
			}' ${CFG_FILE} > ${CFG_FILE}.new &&  cat ${CFG_FILE}.new > ${CFG_FILE} && rm -f ${CFG_FILE}.new

		else
			awk -F: 'BEGIN {
                configured = 0 ;
            }
            {
                if ($1 == "nimbus.authorizer") {
                    if ($2 ~ /^[ \t]*"backtype.storm.security.auth.authorizer.SimpleACLAuthorizer"[ \t]*$/) {
                        configured = 1 ;
                        printf("%s\n",$0) ;
                    }
                    else {
                        printf("#%s\n",$0);
                        printf("nimbus.authorizer: \"backtype.storm.security.auth.authorizer.SimpleACLAuthorizer\"\n") ;
                        configured = 1 ;
                    }
                }
                else {
                    printf("%s\n",$0) ;
                }
            }
            END {
                if (configured == 0) {
                    printf("nimbus.authorizer: \"backtype.storm.security.auth.authorizer.SimpleACLAuthorizer\"\n") ;
                }
            }' ${CFG_FILE} > ${CFG_FILE}.new &&  cat ${CFG_FILE}.new > ${CFG_FILE} && rm -f ${CFG_FILE}.new	
		fi
	fi
fi

#Update Properties to File
#$1 -> propertyName $2 -> newPropertyValue $3 -> fileName
updatePropertyToFile(){
	sed -i 's@^'$1'=[^ ]*$@'$1'='$2'@g' $3
	validate=$(sed '/^\#/d' $3 | grep "^$1"  | tail -n 1 | cut -d "=" -f2-) # for validation
	if test -z "$validate" ; then log "[E] '$1' not found in $3 file while Updating....!!"; exit 1; fi
	echo "Property $1 updated successfully with : '$2'"
}

if [ "${HCOMPONENT_NAME}" = "atlas" ]
then
	if [ "${action}" = "enable" ]
	then
		authName="org.apache.ranger.authorization.atlas.authorizer.RangerAtlasAuthorizer"
	else
		authName="org.apache.atlas.authorize.SimpleAtlasAuthorizer"
	fi

	dt=`date '+%Y%m%d%H%M%S'`
	fn=`ls ${HCOMPONENT_CONF_DIR}/atlas-application.properties 2> /dev/null`
    if [ -f "${fn}" ]
    then
        dn=`dirname ${fn}`
        bn=`basename ${fn}`
        bf=${dn}/.${bn}.${dt}
        echo "backup of ${fn} to ${bf} ..."
        cp ${fn} ${bf}
        echo "Updating properties file: [${fn}] ... "
        updatePropertyToFile atlas.authorizer.impl $authName ${fn}
    fi
fi
#
# Set notice to restart the ${HCOMPONENT_NAME}
#

echo "Ranger Plugin for ${HCOMPONENT_NAME} has been ${action}d. Please restart ${HCOMPONENT_NAME} to ensure that changes are effective."

exit 0
