#!/bin/bash

COMPOSE_PATH="/etc/docker/xivo"
COMPOSE_FILE="docker-xivocc.yml"
CUSTOM_ENV_FILE="custom.env"
FACTORY_ENV_FILE="factory.env"
CONFIGMGT_MIGRATION_LOG_FILE="/var/log/xivo-configmgt-migration.log"
UPGRADE_WORK_DIR="/var/tmp/"
CONFIGMGT_DB_DUMP_FILE="/var/tmp/xivocc_configmgt_xuc_rights_database.sql"

check_response(){
	response=$1
	if [ ${response} = 1 ]; then
		exit 1
	fi
}


ask_if_xivocc_exists() {
	read -p 'Do you have a XiVO CC installed [Y/n]? ' answer
	XIVOCC_ANSWER="${answer:-Y}"
	if [ "$XIVOCC_ANSWER" == 'n' -o "$XIVOCC_ANSWER" == 'N' ]; then
	    echo 'No need to migrate Config-Mgt database to XiVO database then. Exiting.'
		exit 0
	fi
}


display_infos() {
    cat <<EOF

    **********************************************************

    Config-mgt database will be migrated into XiVO database.

    You need to do it to finish the upgrade.
    It will require restarting XiVO and XiVO CC services.

    **********************************************************

EOF
}


check_xivo_version() {
	echo "Checking if xivo >= 2018.09"
	xivo_version=$(LANG='C' apt-cache policy xivo | grep Installed | grep -oE '[0-9]{2,4}\.[0-9]+(\.[0-9]+)?|1\.2\.[0-9]{1,2}' | head -n1)
	if dpkg --compare-versions "$xivo_version" "<<" "2018.09.00"; then
		echo "ERROR: your xivo is not in correct version"
		echo "Please upgrade to XiVO 2018.09 or higher"
		echo "and relaunch confimgt database migration"
	fi
	echo "... yes"
}


ask_to_stop_xivo_services() {
	echo 'XiVO services will be stopped now'
	read -p 'Would you like to migrate configmgt database from XiVO CC now [Y/n]? ' answer
	XIVO_ANSWER="${answer:-Y}"
	if [ "$XIVO_ANSWER" != 'y' -a "$XIVO_ANSWER" != 'Y' ]; then
		exit 1
	fi
}


stop_services() {
	echo "Stopping services..."
	xivo-service stop
}


ask_xivocc_ip_address() {
	XIVOCC_IP=""
	while [ -z "$XIVOCC_IP" ]; do
		XIVOCC_IP=$(whiptail --title "XiVO Upgrade" --inputbox "Please enter XiVO CC database IP address: " 8 50 3>&1 1>&2 2>&3)
		check_response $?
	done
}


check_if_xivocc_reachable() {
	if ping -c 1 ${XIVOCC_IP} &> /dev/null
	then
		return 0
	else
		return 1
	fi
}

check_xivocc_reachable() {
	if ! check_if_xivocc_reachable ; then
		echo "Error: XiVO CC unreachable. Please check you can access XiVO CC via ping and ssh ; then re-run the upgrade."
		exit 1
	fi
}


generate_ssh_keys() {
	ssh-keygen -t rsa -P "" -f ~/.ssh/xivocc_rsa
	cat ~/.ssh/xivocc_rsa.pub | ssh root@${XIVOCC_IP} 'mkdir -p .ssh && cat >> .ssh/authorized_keys'
}


check_if_database_container_running() {
	echo $(ssh -i ~/.ssh/xivocc_rsa root@${XIVOCC_IP} "xivocc-dcomp ps pgxivocc | grep Up | wc -l")
}

check_xivocc_services_stopped() {
	count=$(check_if_database_container_running)
	if (($count > 0)); then
		echo "XiVO: XiVO CC services are still running. They should be stopped before the migration."
		echo "Please stop them and relaunch the upgrade"
		exit 1
	fi
}


xuc_rights_start_database() {
	echo "XiVO CC: Starting database container."
	ssh -i ~/.ssh/xivocc_rsa root@${XIVOCC_IP} "xivocc-dcomp start pgxivocc"

	DB_RUNNING=0
	while [ "$DB_RUNNING" -ne "1" ]; do
		output=$(ssh -i ~/.ssh/xivocc_rsa root@${XIVOCC_IP} "xivocc-dcomp ps pgxivocc" 2>&1)
		DB_RUNNING=$(echo ${output} | grep "Up" | wc -l)
		sleep 1
		i=$((i+1))
		if (($i > 3)); then
			echo "XiVO CC: Unable to start database container"
			exit 1
	fi
	done
	echo "XiVO CC: Database container started."
}

xuc_rights_verify_schema_version() {
	last_play_evol_script=$(psql -tq --dbname=postgresql://xuc:xuc@${XIVOCC_IP}:5443/xuc_rights -c "select max(id) from play_evolutions where state='applied';")
	echo "Last play_evolutions script applied on configmgt (xuc_rights) db was ${last_play_evol_script}"
	if [ "${last_play_evol_script}" -lt "11" ]; then
		echo "Configmgt database is too old. We need to stop."
		echo "First, upgrade your CC installation to one of these versions:"
		echo " - Five (2017.03)"
		echo " - or Polaris (2017.11)"
		echo "And then re-run this upgrade script."
		exit 1
	else
		echo "... OK, continue"
	fi
}

xuc_rights_export_database_from_xivocc() {
	echo "XiVO CC: Exporting database xuc_rights."
	pg_dump --data-only --disable-triggers --exclude-table="play_evolutions" --dbname=postgresql://xuc:xuc@${XIVOCC_IP}:5443/xuc_rights > ${CONFIGMGT_DB_DUMP_FILE}
}

xuc_rights_revoke_writable_privileges() {
	echo "XiVO CC: Revoking writable privileges from xuc_rights."
	REVOKE_RESULT=$(psql --dbname=postgresql://xuc:xuc@${XIVOCC_IP}:5443/xuc_rights -c "REVOKE INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER ON ALL TABLES IN SCHEMA public, xc FROM xuc;")
	if [ "$REVOKE_RESULT" != "REVOKE" ]; then
		echo "ERROR: Revoke user xuc privileges failed"
	fi
}

xuc_rights_import_database() {
    update_replication_state_sql="""
        UPDATE replication_state
        SET val=(
          CASE WHEN (SELECT MAX(reference_number) FROM callback_request) IS NOT NULL
               THEN (SELECT MAX(reference_number) FROM callback_request)
               ELSE 0
          END)
        WHERE name='callback_request';
        """

	echo "XiVO: Importing database dump from xuc_rights to asterisk database."
	sudo -u postgres psql asterisk -c "CREATE USER xuc WITH PASSWORD 'xuc';"
	sudo -u postgres psql asterisk -c "TRUNCATE preferred_callback_period CASCADE;"
	sudo -u postgres psql asterisk < ${CONFIGMGT_DB_DUMP_FILE}
	sudo -u postgres psql asterisk -c "REASSIGN OWNED BY xuc TO asterisk;"
	sudo -u postgres psql asterisk -c "DROP USER xuc;"
	sudo -u postgres psql asterisk -c "$update_replication_state_sql"
}

xuc_rigths_migrate_db() {
	# Add recording_access right to current supervisor
	sudo -u postgres psql asterisk -c "INSERT INTO rights(user_id, category, category_id) SELECT id,'recording_access','1' FROM users WHERE type = 'supervisor'"
}

xuc_rights_stop_database() {
	echo "XiVO CC: Stopping database container."
	ssh -i ~/.ssh/xivocc_rsa root@${XIVOCC_IP} "xivocc-dcomp stop pgxivocc"
}

db_migration_from_xivocc() {
	xuc_rights_start_database
	xuc_rights_verify_schema_version
	xuc_rights_export_database_from_xivocc
	xuc_rights_revoke_writable_privileges
	xuc_rights_import_database
	xuc_rigths_migrate_db
	xuc_rights_stop_database
}


pull_configmgt_image() {
	echo "XiVO: downloading config-mgt image"
	/usr/bin/xivo-dcomp pull
}

start_services() {
	echo "Starting services..."
	/etc/init.d/postgresql restart >> $CONFIGMGT_MIGRATION_LOG_FILE
	xivo-service start
}



cd ${UPGRADE_WORK_DIR}
ask_if_xivocc_exists
display_infos
check_xivo_version
ask_to_stop_xivo_services
stop_services
ask_xivocc_ip_address
check_xivocc_reachable
generate_ssh_keys
check_xivocc_services_stopped
db_migration_from_xivocc
pull_configmgt_image
start_services


cat <<EOF

  *********** Config-mgt database migration from XiVOCC successful ************

  Don't forget to restart the services on your XiVO CC
  You also need to upgrade your XiVO CC to the same version of your XiVO PBX

EOF
