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

COMPONENT_NAME=hive
CFG_DIR=/etc/${COMPONENT_NAME}/conf
XASECURE_ROOT=/etc/xasecure/${COMPONENT_NAME}
BACKUP_TYPE=pre
CUR_VERSION_FILE=${XASECURE_ROOT}/.current_version
CUR_CFG_DIR_FILE=${XASECURE_ROOT}/.config_dir
if [ -f ${CUR_VERSION_FILE} ]
then
	XASECURE_VERSION=`cat ${CUR_VERSION_FILE}`
	PRE_INSTALL_CONFIG=${XASECURE_ROOT}/${BACKUP_TYPE}-${XASECURE_VERSION}
	dt=`date '+%Y%m%d%H%M%S'`
	if [ -d "${PRE_INSTALL_CONFIG}" ]
	then
		if [ -f ${CUR_CFG_DIR_FILE} ] 
		then
			CFG_DIR=`cat ${CUR_CFG_DIR_FILE}`
		fi 
		[ -d ${CFG_DIR} ] && mv ${CFG_DIR} ${CFG_DIR}-${dt}
		( cd ${PRE_INSTALL_CONFIG} ; find . -print | cpio -pdm ${CFG_DIR} )
		[ -f ${CUR_VERSION_FILE} ] && mv ${CUR_VERSION_FILE} ${CUR_VERSION_FILE}-uninstalled-${dt}
		echo "XASecure version - ${XASECURE_VERSION} has been uninstalled successfully."
	else
		echo "ERROR: Unable to find pre-install configuration directory: [${PRE_INSTALL_CONFIG}]"
		exit 1
	fi
else
	cd ${CFG_DIR}
	saved_files=`find . -type f -name '.*' |  sort | grep -v -- '-new.' | grep '[0-9]*$' | grep -v -- '-[0-9]*$' | sed -e 's:\.[0-9]*$::' | sed -e 's:^./::' | sort -u`
	dt=`date '+%Y%m%d%H%M%S'`
	if [ "${saved_files}" != "" ]
	then
	        for f in ${saved_files}
	        do
	                oldf=`ls ${f}.[0-9]* | sort | head -1`
	                if [ -f "${oldf}" ]
	                then
	                        nf=`echo ${f} | sed -e 's:^\.::'`
	                        if [ -f "${nf}" ]
	                        then
	                                echo "+cp -p ${nf} .${nf}-${dt}"
	                                cp -p ${nf} .${nf}-${dt}
	                                echo "+cp ${oldf} ${nf}"
	                                cp ${oldf} ${nf}
	                        else
	                                echo "ERROR: ${nf} not found to save. However, old file is being recovered."
	                                echo "+cp -p ${oldf} ${nf}"
	                                cp -p ${oldf} ${nf}
	                        fi
	                fi
	        done
	        echo "XASecure configuration has been uninstalled successfully."
	fi
fi