#!/bin/sh

set -e

REPO_URL=http://autoinstall.plesk.com/panel-migrator/branches/0.1.11-preview
PPA_MOVING_GUIDE_URL=http://download1.parallels.net/ppa/11.5/docs/en-US/pdf/ppa_moving_to.pdf
PPA_OPERATIONS_GUIDE_URL=http://download1.parallels.com/ppa/11.5/docs/en-US/pdf/ppa_operations_guide.pdf
PACKAGES_TO_INSTALL="panel-migrator-tool panel-migrator-lib"

die() {
	local error="$1"
	local solution="$2"
	echo "ERROR: $error" 2>&1
	echo "$solution" 2>&1
	exit 1
}

print_congratulations() {
	local action_performed="$1"
	
	cat << END

CONGRATULATIONS! You have successfully $action_performed the Panel Migrator.

To get help on the tools, run the following commands:
For the transfer tool:
  panel-migrator help
For the move subscriptions between nodes tool:
  ppa-move-subscriptions help

To get the detailed instructions on how to perform the move to Plesk or PPA,
follow the Panel Migrator guide at $PPA_MOVING_GUIDE_URL
To get the detailed instructions on how to perform the move subscriptions between PPA nodes,
follow the Moving Subscriptions Between Nodes section in Operations guide at $PPA_OPERATIONS_GUIDE_URL
END
}

die_invalid_usage() {
	local message="$1"
	cat << END
Invalid arguments passed.
Usage: installer.sh [--upgrade]
To install the Panel Migrator run the script without any arguments:
# ./installer.sh
To upgrade the Panel Migrator to the latest version run the script with "--upgrade" argument:
# ./installer.sh --upgrade
To check for updates run the script with "--check-updates" argument:
# ./installer.sh --check-updates
END
	exit 1
}

log_step() {
	local message="$1"
	echo "`date` ===> $message..."
}

is_rpm() {
	if [ ! -z "`rpm --version 2>/dev/null || true`" ]; then
		echo 1
	fi
}

is_redhat() {
	if [ -f /etc/redhat-release ]; then
		echo 1
	fi
}

download_repo_file() {
	log_step "Downloading the Panel Migrator repo file"
	if [ $(is_rpm) ]; then
		if [ $(is_redhat) ]; then
			repo_url=$REPO_URL/panel-migrator-$(get_os_name).repo
			wget -q $repo_url -O /etc/yum.repos.d/panel-migrator.repo
			yum makecache
		else
			repo_url=$REPO_URL/repo/$(get_os_name)-$(get_os_version)-$(get_os_arch)
			zypper --non-interactive removerepo panel-migrator
			zypper clean
			zypper --non-interactive addrepo --no-gpgcheck $repo_url panel-migrator
		fi
	else
		repo_url=$REPO_URL/panel-migrator-$(get_os_name)-$(get_os_version)-$(get_os_arch).list
		wget -q $repo_url -O /etc/apt/sources.list.d/panel-migrator.list
		apt-get update
	fi
}

get_package_manager_utility_name() {
	if [ $(is_rpm) ]; then
		if [ $(is_redhat) ]; then
			echo "yum"
		else
			echo "zypper"
		fi
	else
		echo "apt-get"
	fi
}

get_package_manager_utility_call_prefix() {
	if [ $(is_rpm) ]; then
		if [ $(is_redhat) ]; then
			echo "$(get_package_manager_utility_name) -y"
		else
			echo "$(get_package_manager_utility_name) --non-interactive"
		fi
	else
		echo "$(get_package_manager_utility_name) --yes --force-yes"
	fi
}

check_updates() {
	download_repo_file > /dev/null 2>&1
	if [ ! -z "$(is_updates_available)" ]; then
		echo 'Updates available, use --upgrade command to install it.'
	fi
}

upgrade() {
	download_repo_file
	log_step "Upgrading the Panel Migrator packages"
	remove_old_packages

	for pkg in $PACKAGES_TO_INSTALL; do
		if [ ! $(is_package_installed $pkg) ]; then
			$(get_package_manager_utility_call_prefix) install "$pkg"
		else
			if [ $(is_rpm) ]; then
				$(get_package_manager_utility_call_prefix) update "$pkg"
			else
				$(get_package_manager_utility_call_prefix) install "$pkg"
			fi
		fi
	done

	print_congratulations "upgraded"
}

remove_old_packages() {
	# old packages may be installed only on rpm OSes,
	# so skip this operation for others
	if [ ! $(is_rpm) ]; then
		return
	fi

	# previous Panel Migrator packages has "ppa-migrator-*" name prefix,
	# so remove ppa-migrator-common package (entail automatic removing of all dependent packages)
	if [ $(is_package_installed "ppa-migrator-common") ]; then
		$(get_package_manager_utility_call_prefix) remove ppa-migrator-common
	fi

	# python package was renamed from python2.7 to panel-migrator-python,
	# python module packages also was renamed, so remove python2.7 package,
	# that entail automatic removing of all dependent packages
	if [ $(is_package_installed "python2.7") ]; then
		$(get_package_manager_utility_call_prefix) remove python2.7
	fi

	# in old PPA 11.1 migrator releases (not the latest PPA 11.1 migrator release)
	# several python module packages did not have python2.7-* prefix,
	# so remove such packages
	old_python_packages="PyYAML paramiko pysmb psycopg2"
	old_python_packages_installed=""
	for pkg in $old_python_packages; do
		if [ $(is_package_installed $pkg) ]; then
			old_python_packages_installed="$old_python_packages_installed $pkg"
		fi
	done
	if [ ! -z "$old_python_packages_installed" ]; then
		log_step "Remove old packages"
		# remove "old" python module packages;
		# ignore cases when there are dependencies apart of migration tool as we don't know
		# who depends on them and whether it is safe to remove it;
		# in that case need to resolve dependencies and remove useless packages manually
		rpm -e $old_python_packages_installed || true
	fi
}

is_updates_available() {
	if [ $(is_rpm) ]; then
		if [ $(is_redhat) ]; then
			updates=`yum check-update -q "$PACKAGES_TO_INSTALL"`
		else
			updates=`zypper -q list-updates -r panel-migrator`
		fi
	else
		pattern=""
		for package in $PACKAGES_TO_INSTALL; do
			if [ ! -z "$pattern" ]; then pattern="$pattern\|$package"; else pattern="$package"; fi
		done
		updates=`apt-get -s -q upgrade | grep "$pattern" || true`
	fi
	if [ ! -z "$updates" ]; then
		echo 1
	fi
}

is_package_installed() {
	package_name=$1
	if [ $(is_rpm) ]; then
		result=`rpm -q --qf "%{NAME}.%{ARCH}\n" --all | grep "^${package_name}" 2>/dev/null | head -n1 || true`
	else
		result=`dpkg-query -W -f='${Status}\n' "${package_name}" | awk '{ if ($3 == "installed") print "installed" }'`
	fi
	if [ ! -z $result ]; then
		echo 1
	fi
}

install() {
	download_repo_file
	log_step "Installing the Panel Migrator packages"
	$(get_package_manager_utility_call_prefix) install $PACKAGES_TO_INSTALL
	# check packages existence after intall operation as it does not set error when there are no packages
	for pkg in $PACKAGES_TO_INSTALL; do
		if [ ! $(is_package_installed $pkg) ]; then
			die "Unable to install $pkg." "Install $pkg manually by running: $(get_package_manager_utility_name) install $pkg"
		fi
	done

	print_congratulations "installed"
}
get_os_version_info_filename() {
	if [ $(is_rpm) ]; then
		echo "/etc/redhat-release"
	else
		echo "/etc/issue"
	fi
}

get_os_name() {
	# use /etc/os-release if it exist
	if [ -f "/etc/os-release" ]; then
		echo `cat /etc/os-release | awk 'BEGIN { FS = "=" } /^NAME=/{ gsub(/"/, "", $2); split($2, data, " "); print data[1] }'`
		return
	fi
	case `cat "$(get_os_version_info_filename)"` in
	CentOS*)
		echo "CentOS"
		;;
	Red\ Hat\ Enterprise\ Linux*)
		echo "RedHat"
		;;
	CloudLinux*)
		echo "CloudLinux"
		;;
	Debian*)
		echo "Debian"
		;;
	Ubuntu*)
		echo "Ubuntu"
		;;
	esac
}

get_os_version() {
	# use /etc/os-release if it exist
	if [ -f "/etc/os-release" ]; then
		echo `cat /etc/os-release | awk 'BEGIN { FS = "=" } /^VERSION=/{ gsub(/"/, "", $2); split($2, data, " "); split(data[1], data, "."); print data[1] }'`
		return
	fi
	os_version_info=`cat "$(get_os_version_info_filename)"`
	number=`echo "$os_version_info" | sed 's/[^0-9]*\([0-9]*\).*/\1/' | head -n1`
	if [ ! -z "`echo "$os_version_info" | grep 'Red Hat Enterprise Linux Server' || true`" ]; then
		echo "${number}Server"
	else
		echo $number
	fi
}

get_os_arch() {
	if [ `uname -m` = "x86_64" ]; then
		echo "x86_64"
	else
		echo "i386"
	fi
}

check_os_supported() {
	os_name=$(get_os_name)
	os_version=$(get_os_version)

	# special check for Red Hat
	if [ $os_name = "RedHat" ] && [ ! `echo "$os_version" | grep 'Server' || true` ]; then
		cat 2>&1 << END
The installer has detected that you use a RHEL edition other than Server. The installer does not support such systems.
To install the tools, you should:
1. Update the yum repositories directory with the command:
wget $REPO_URL/panel-migrator-RedHat.repo -O /etc/yum.repos.d/panel-migrator.repo
2. Set the \$releasever parameter in the /etc/yum.repos.d/panel-migrator.repo file to 5Server (for RHEL 5.x) or 6Server (for RHEL 6.x).
3. Install the tools with the command:
yum install $PACKAGES_TO_INSTALL
END
		exit 1
	fi

	# check, that current OS is in list of supported OSes
	os="$os_name-$os_version"
	if
		[ $os = "CentOS-5" ] ||
		[ $os = "CentOS-6" ] ||
		[ $os = "CentOS-7" ] ||
		[ $os = "RedHat-5Server" ] ||
		[ $os = "RedHat-6Server" ] ||
		[ $os = "RedHat-7Server" ] ||
		[ $os = "CloudLinux-5" ] ||
		[ $os = "CloudLinux-6" ] ||
		[ $os = "openSUSE-13" ] ||
		[ $os = "Debian-6" ] ||
		[ $os = "Ubuntu-12" ] ||
		[ $os = "Debian-7" ] ||
		[ $os = "Ubuntu-14" ] ||
		[ $os = "Debian-8" ]
	then
		return
	fi

	die "Your operating system is not supported." "The tools support only CentOS / RHEL 5, 6, 7 or Debian 6."
}

# check, that current OS supported by this installer
check_os_supported

# check, that all required progarams are installed
if [ $(is_rpm) ]; then
	if [ $(is_redhat) ]; then
		required_programs="rpm yum wget sed"
	else
		required_programs="rpm zypper wget sed"
	fi
else
	required_programs="dpkg apt-get wget sed"
fi
for program in $required_programs; do
	$program --version > /dev/null || die "Unable to run $program." "The installer requires the following programs: $required_programs."
done

# perform installation/upgrade
pkgs_installed=""
if [ $# -eq 0 ]; then
	for pkg in $PACKAGES_TO_INSTALL; do
		if [ $(is_package_installed $pkg) ]; then
			pkgs_installed="$pkgs_installed $pkg"
		fi
	done
	# if there are any root migration tool package - consider that migration tools are already installed (at least partially)
	if [ ! -z "$pkgs_installed" ]; then
		echo 'The Panel Migrator is already installed.'
		echo 'If you want to upgrade the Panel Migrator to the latest version run installer with "--upgrade" argument'
	else
		install
	fi
elif [ $# -eq 1 ]; then
	if [ "$1" = '--upgrade' ]; then
		upgrade
	elif [ "$1" = '--check-updates' ]; then
		check_updates
	else
		die_invalid_usage
	fi
else
	die_invalid_usage
fi

exit 0