#!/bin/sh


set -e

if [ "X${PLESK_INSTALLER_DEBUG}" != "X" ]; then
	set -x
fi

ADMIN="admin"
ADMIN_PASSWORD=`cat /etc/psa/.psa.shadow`
NAME="plesk-billing"	# product name
DB_NAME="billing"
DB_HOST="localhost"
DB_USER="$DB_NAME"

PORT="8443"

PLESK_DIR="/usr/local/psa"

PLESK_DB_NAME="psa"

random_str()
{
	local len="$1"	# random string length
	if [ "X$len" = "X" ]; then
		len=40	# like sha1
	fi
	dd if=/dev/urandom count=20 2>/dev/null | openssl sha1 | cut -c 1-$len
}

escape_str()
{
	# converts ' --> \'  and  \ --> \\
	echo "$1" | sed -e 's|\(['\''\]\)|\\\1|g'	# for vim syntax - '
}

sha1()
{
	echo -n "$1" | openssl sha1
}

export DB_PASSWORD=`random_str`

db_query()
{
	local query="$1";
	local database="${2:-$DB_NAME}"
	mysql -u "$ADMIN" "-p$ADMIN_PASSWORD" -h "$DB_HOST" -A --skip-column-names --batch --raw -e "$query" "$database"	# MySQL 3.23 doesn't recognize --skip-auto-rehash option, used -A instead
}

echo2()
{
	echo "$1" >&2
}

die()
{
	echo2 "$1"
	exit 1;
}

drop_dbuser()
{
	db_query "REVOKE ALL ON \`$DB_NAME\`.* FROM '$DB_USER'@'localhost'"	# for mysql server < 5.0.2
	db_query "DROP USER '$DB_USER'@'localhost'"
	res=$?
	db_query "FLUSH PRIVILEGES"
	return $res
}

drop_database()
{
	mysqladmin -u "$ADMIN" "-p$ADMIN_PASSWORD" -h "$DB_HOST" drop --force "$DB_NAME"
}

create_database()
{
	local database_name="$DB_NAME";
	local i=10;

	while [ $i -gt 0 ]; do

		mysqladmin -u "$ADMIN" "-p$ADMIN_PASSWORD" -h "$DB_HOST" create "$database_name" 2>/dev/null && break

		database_name="${DB_NAME}_`random_str 4`"
		i=`expr $i - 1`

	done;

	if [ $i -eq 0 ]; then
		DB_NAME=""
		return 1;
	fi

	DB_NAME="$database_name"
	DB_USER="$DB_NAME"	# try to create DB user with the same username as database name

	return 0;
}

create_dbuser()
{
	local user="$DB_USER"
	local i=10;

	while [ $i -gt 0 ]; do

		#db_query "CREATE USER '$user'@'localhost' IDENTIFIED BY '$DB_PASSWORD'"	# works only for mysql server >= 5.0.2
		db_query "INSERT INTO mysql.user (User, Host, Password) VALUES ('$user', 'localhost', PASSWORD('$DB_PASSWORD'))" 2>/dev/null && break

		user="${DB_USER}_`random_str 4`"
		i=`expr $i - 1`

	done;

	if [ $i -eq 0 ]; then
		DB_USER=""
		return 1;
	fi

	db_query "FLUSH PRIVILEGES" || return 1

	DB_USER="$user"

	res=0
	db_query "GRANT ALL ON \`$DB_NAME\`.* TO '$DB_USER'@'localhost'" || res=1
	if [ $res -eq 1 ]; then
		# rollback
		drop_dbuser
		return 1;
	fi

	db_query "FLUSH PRIVILEGES" || return 1

	return 0;
}

create_config()
{
	local config_file="$INSTALL_PREFIX/$NAME/lib-billing/include/config/config.php"

	touch "$config_file" || return 1

	chmod 400 "$config_file" || return 1

	local standard_url="$SERVER_NAME:$PORT/$NAME"

	sed -e "s|@@DB_HOST@@|localhost|g" \
		-e "s|@@DB_NAME@@|$DB_USER|g" \
		-e "s|@@DB_USER@@|$DB_USER|g" \
		-e "s|@@DB_PASSWORD@@|$DB_PASSWORD|g" \
		-e "s|@@SCHEME@@|https|g" \
		-e "s|@@STANDARD_URL@@|$standard_url|g" \
		-e "s|@@PORT@@|$PORT|g" \
		-e "s|@@TMP_DIR@@|/tmp|g" \
		< "$config_file.tmpl" > "$config_file" || return 1

	chown psaadm "$config_file" || return 1

	return 0
}

set_config_perm()
{
	local config_dir="$INSTALL_PREFIX/$NAME/lib-billing/include/config"

	(
		cd "$config_dir" && \
		chmod 400 gateway.php panel.php registrar.php && \
		chown psaadm gateway.php panel.php registrar.php
	) || return 1
}

create_db_struct()
{
	db_dump="$SHARE_DIR/database_dump.sql"
	if [ ! -f "$db_dump" ]; then
		echo2 "Unable to find database dump file: '$db_dump'"
		return 1
	fi

	mysql -u "$ADMIN" "-p$ADMIN_PASSWORD" -h "$DB_HOST" "$DB_NAME" < "$db_dump" || return 1

	# set up unique remote_access_admin_hash
	db_query "UPDATE admins SET admin_remote_access_hash='`random_str`' WHERE admin_username='admin'" || return 1
	db_query "UPDATE admins SET admin_remote_access_hash='`random_str`' WHERE admin_username='admin_ezorder'" || return 1
	db_query "UPDATE admins SET admin_remote_access_hash='`random_str`' WHERE admin_username='admin_api'" || return 1
	db_query "UPDATE admins SET admin_remote_access_hash='`random_str`' WHERE admin_username='cronadmin'" || return 1

	local base_url="https://$SERVER_NAME:$PORT"
	# set up companies
	company_client_url="$base_url/$NAME/client/"
	company_order_url="$base_url/$NAME/order/"
	db_query "UPDATE companies SET company_client_url='$company_client_url', company_order_url='$company_order_url'" || return 1

	# set up Plesk connection parameters
	# escape password properly
	password=`escape_str "$ADMIN_PASSWORD"`
	db_query "UPDATE config_params SET config_param_value='$password' WHERE config_param_name='modulePassword' AND config_param_description='TRANS_PLESK_PASSWORD_DESC'" || return 1

	shared_ip=`get_shared_ip` || return 1
	if [ -n "$shared_ip" ]; then
		db_query "UPDATE config_params SET config_param_value='$shared_ip' WHERE config_param_name='ip' AND config_param_description='TRANS_PANEL_PLESK_SHARED_IP_DESC'" || return 1
	fi

	# update api parameter
	db_query "UPDATE config_params SET config_param_value='$base_url' WHERE config_param_name='api' AND config_param_trans_key='TRANS_PLESK_URL'" || return 1

	# update Display_Logo parameter
	db_query "UPDATE config_params SET config_param_value='$base_url/$NAME/lib-themes/default/lib-billing/images/logos/logo.gif' WHERE config_param_name='Display_Logo'" || return 1

	# update IPN_URL parameter
	db_query "UPDATE config_params SET config_param_value='$base_url/$NAME/lib-mbapi/include/modules/gateway/return/paypal.php' WHERE config_param_name='IPN_URL'" || return 1

	# set up order form params
	db_query "UPDATE order_form_params SET order_form_param_value='$base_url/$NAME/order/' WHERE order_form_param_name='continue_shopping_url'" || return 1
	db_query "UPDATE order_form_params SET order_form_param_value='$base_url/' WHERE order_form_param_name='terms_url'" || return 1

	return 0
}

get_shared_ip()
{
	"$PLESK_DIR/bin/ipmanage" --ip_list | awk '/^[0-9][[:space:]]+S/ {split($3, a, "[:/]"); print a[2]; nextfile}'
}

set_admin_info()
{
	# set up ModernBill admin password the same as in Plesk
	# encrypt admin password
	local password=`sha1 "$ADMIN_PASSWORD"`
	password=`sha1 "$password"`
	db_query "UPDATE admins SET admin_password='$password'" || return 1

	psa_configured=`db_query "SELECT val FROM misc WHERE param='psa_configured'" "$PLESK_DB_NAME"` || die "Unable to define if Plesk is configured or not"

	if [ "X$psa_configured" != "Xtrue" ]; then	# Plesk is not configured, do not copy admin info from Plesk
		return 0;
	fi

	# fetch admin's personal info
	client_id=`db_query 'SELECT id FROM clients WHERE type="admin" LIMIT 1' "$PLESK_DB_NAME"` || return 1

	# personal name
	pname=`db_query "SELECT pname FROM clients WHERE id='$client_id'" "$PLESK_DB_NAME"`
	email=`db_query "SELECT email FROM clients WHERE id='$client_id'" "$PLESK_DB_NAME"`
	company=`db_query "SELECT cname FROM clients WHERE id='$client_id'" "$PLESK_DB_NAME"`
	phone=`db_query "SELECT phone FROM clients WHERE id='$client_id'" "$PLESK_DB_NAME"`
	fax=`db_query "SELECT fax FROM clients WHERE id='$client_id'" "$PLESK_DB_NAME"`
	address=`db_query "SELECT address FROM clients WHERE id='$client_id'" "$PLESK_DB_NAME"`
	city=`db_query "SELECT city FROM clients WHERE id='$client_id'" "$PLESK_DB_NAME"`
	zip=`db_query "SELECT pcode FROM clients WHERE id='$client_id'" "$PLESK_DB_NAME"`
	state=`db_query "SELECT state FROM clients WHERE id='$client_id'" "$PLESK_DB_NAME"`
	country=`db_query "SELECT country FROM clients WHERE id='$client_id'" "$PLESK_DB_NAME"`

	# update plesk-billing

	pname=`escape_str "$pname"`
	email=`escape_str "$email"`
	company=`escape_str "$company"`
	phone=`escape_str "$phone"`
	fax=`escape_str "$fax"`

	address=`escape_str "$address"`
	city=`escape_str "$city"`
	zip=`escape_str "$zip"`
	state=`escape_str "$state"`
	country=`escape_str "$country"`

	# convert country into the country_id
	country_id=`db_query "SELECT countries_id FROM countries WHERE countries_iso_2 = '$country'"`

	db_query "UPDATE admins SET admin_last_name='$pname', admin_email='$email', countries_id='$country_id' WHERE admin_id=1"

	db_query "UPDATE companies SET company_name='$company', company_email='$email', company_address_1='$address', company_city='$city', company_state='$state', company_zip='$zip', countries_id='$country_id', company_phone1='$phone', company_fax='$fax', countries_id='$country_id' WHERE company_id=1"
}

set_ppb_connection()
{
	# define clients ID for admin user
	client_id=`db_query 'SELECT id FROM clients WHERE type="admin" LIMIT 1' "$PLESK_DB_NAME"` || return 1

	# set up admin_remote_access_hash
	admin_remote_access_hash=`db_query 'SELECT admin_remote_access_hash FROM admins WHERE admin_username="admin_api"'` || return 1
	admin_remote_access_hash=`escape_str "$admin_remote_access_hash"`

	db_query "REPLACE INTO cl_param VALUES($client_id, 'remote-access-hash', '$admin_remote_access_hash')" "$PLESK_DB_NAME" || return 1

	# set up ppb_url
	ppb_url=`escape_str "https://$SERVER_NAME:$PORT/$NAME/"`
	db_query "REPLACE INTO cl_param VALUES($client_id, 'ppb-url', '$ppb_url')" "$PLESK_DB_NAME" || return 1
}

unset_ppb_connection()
{
	db_query "DELETE FROM cl_param WHERE param in ('ppb-url', 'remote-access-hash')" "$PLESK_DB_NAME" || return 1
}

set_crontab()
{	
	# PPB 5.6: */5 * * * * $PLESK_DIR/admin/bin/php $INSTALL_PREFIX/$NAME/app-modernbill-admin/sbin/runevents.php
	# PPB 6.0: */5 * * * * $PLESK_DIR/admin/bin/php $INSTALL_PREFIX/$NAME/admin/sbin/runevents.php

	# remove current crontab task
	unset_crontab

	# create file for crontab
	crontab_file="`mktemp /tmp/$NAME.crontab-XXXXXX`" || return 1

	# fetch crontab
	crontab -u psaadm -l > "$crontab_file" 2>/dev/null || true # ignore "no crontab for psaadm" error

	record="*/5 * * * * $PLESK_DIR/admin/bin/php $INSTALL_PREFIX/$NAME/admin/sbin/runevents.php"
	echo "$record" >> "$crontab_file" || return 1
	crontab -u psaadm "$crontab_file" || return 1

	rm -f "$crontab_file" || return 1
}

# remove crontab record
unset_crontab()
{

	# create file for crontab
	crontab_file="`mktemp /tmp/$NAME.crontab-XXXXXX`" || return 1

	# fetch crontab
	crontab -u psaadm -l > "$crontab_file" # no error handling due to "no crontab for psaadm" error possible
	grep -v "admin/sbin/runevents.php" < "$crontab_file" > "$crontab_file.tmp"
	mv "$crontab_file.tmp" "$crontab_file" || return 1

	if [ -s "$crontab_file" ]; then
		crontab -u psaadm "$crontab_file" || return 1
	else
		echo 'y' | crontab -u psaadm -r 2>/dev/null	# no error handling due to "no crontab for psaadm" error possible
	fi

	rm -f "$crontab_file" || return 1
}

print_congratulations()
{
	echo
	echo "                  Congratulations!"
 	echo " Parallels Plesk Billing has been successfully installed on your server."
	echo
 	echo " Use the following URLs to access the system."
	echo
 	echo " For administrator's panel:"
 	echo " https://$SERVER_NAME:8443/plesk-billing/admin"
 	echo " For client's panel:"
 	echo " https://$SERVER_NAME:8443/plesk-billing/client"
 	echo " For access to the ordering system:"
 	echo " https://$SERVER_NAME:8443/plesk-billing/order"
	echo
	echo " Use the login name 'admin' and the same password that you use for logging in to"
	echo " Plesk Control Panel."
	echo
	echo " All Parallels Plesk Billing documentation is available at"
 	echo " http://www.pleskbilling.com/support/manual/"
	echo
}

rename_modernbill_dirs()
{
	local new_config_file="$INSTALL_PREFIX/$NAME/lib-billing/include/config/config.php"
	if [ ! -f "$new_config_file" ]; then
		touch "$new_config_file" || return 1
		chmod 400 "$new_config_file" || return 1
		local old_config_file="$INSTALL_PREFIX/$NAME/lib-modernbill/include/config/config.php"
		sed -e "s|lib-modernbill|lib-billing|g" < "$old_config_file" > "$new_config_file" || return 1
		chown psaadm "$new_config_file" || return 1
	fi

	rm -rf "$INSTALL_PREFIX/$NAME/lib-modernbill/" || return 1

	db_query "UPDATE companies SET company_client_url=REPLACE(company_client_url, '/app-modernbill-client/', '/client/'), company_order_url=REPLACE(company_order_url, '/app-modernbill-order/', '/order/')" || return 1
	db_query "UPDATE config_params SET config_param_value=REPLACE(config_param_value, '/lib-modernbill/', '/lib-billing/') WHERE config_param_name='Display_Logo'" || return 1
	db_query "UPDATE order_form_params SET order_form_param_value=REPLACE(order_form_param_value, '/app-modernbill-order/', '/order/') WHERE order_form_param_name='continue_shopping_url'" || return 1
}

restart_sw_cp_server()
{
	if [ -e "/etc/init.d/sw-cp-server" ]; then
		/etc/init.d/sw-cp-server restart
	elif [ -e "/etc/rc.d/sw-cp-server" ]; then
		/etc/rc.d/sw-cp-server restart
	fi
}
#INSTALL_PREFIX="$PKG_PREFIX"
INSTALL_PREFIX="/usr/local"
SHARE_DIR="/usr/local/share/$NAME"

if [ "POST-INSTALL" = "$2" ]; then
	if [ -z "$UPGRADE_PORT" ]; then
		mode="install"
	else
		mode="upgrade"
	fi
elif [ "DEINSTALL" = "$2" ]; then
	mode="remove"
else
	exit 0	# PRE-INSTALL or POST-DEINSTALL
fi

case "$mode" in

	remove)

		# unregister Plesk Billing in Plesk
		unset_ppb_connection || echo2 "Unable to remove Plesk Billing connection info from Plesk's database"

		# unset crontab
		unset_crontab || echo2 "Unable to remove crontab task"
		;;

	install)
		;;
	upgrade)
		;;

	*)
		echo2 "pre-uninstall called with unknown argument \`$mode'"
		exit 0
		;;
esac

exit 0
