#!/bin/bash

. ${TOOLKIT}-functions.sh


do_query()
{
	echo " run sql: $@" | sed -e 's/PASSWORD.*/PASSWORD.../g'
	local out=$(echo "$@" | mysql 2>&1)
	echo "$out"
	echo "$out" | grep -q "ERROR" && return 1
	return 0
}


start_temp_server()
{
	local pid=
	local retry=0

	echo -en "  starting temporary server (socket, without grant tables) ...\n"

	mysqld_safe --skip-grant-tables --skip-networking &
	while [ ! -e $sockfile ]
	do
		retry=$(($retry+1))
		[ $retry -gt 10 ] && {
			echo "error: too many retry waiting for sockfile '$sockfile', abort" 
			exit 1
		}
		sleep 1
	done
	pid=$(cat $pidfile)
	echo -e "\n  ok, pid=$pid\n"
	return 0
}


stop_temp_server()
{
	local pid=
	[ -f $pidfile ] || return 0

	pid=$(cat $pidfile)
	echo -en "  stopping temporary server, pid=$pid ... "
	kill $pid
	sleep 2
	echo "ok"
	return 0
}



# (MAIN)

mysql_tmpdir=$(jtconf mysql.tmpdir)
mysql_datadir=$(jtconf mysql.datadir)
mysql_init=$(jtconf mysql.initname)
mysql_confdir="/etc/mysql/conf.d"

packagename=$(jtconf mysql.packagename)
has_mariadb=false

pid=
pidfile="/run/mysqld/mysqld.pid"
sockfile="/run/mysqld/mysqld.sock"

[ "X$packagename" = "Xmariadb" ] && {
	echo -e "  USES MARIADB AS MYSQL REPLACEMENT"
	has_mariadb=true
	mysql_confdir="/etc/mysql/mariadb.conf.d"
}


# SETUP NETWORK ACCESS: this must be done early
#
installfile ku-network.cnf $mysql_confdir/ root:root 640


# UPDATE ROOT PW IF NEEDED
#
# (on stock db if just installed, or on custom datadir if
# already configured by kusa)
#
restart_needed=true

if $has_mariadb
then
	rootpw=$(jtconf mysql.root_pw)	|| exit_missing_define mysql.root_pw
	hashed_pw=$(echo "$rootpw" | openssl passwd -1 -salt MY -stdin)

	# root password setup
	#
	# uses manual method, since in new debian systems the password is
	# no more saved in debconf db
	#
	# to avoid unnecessary changes and server restart, we save an hashed
	# version of password in the '$savepass' file
	#
	savepass="/etc/kusa/files/$MODNAME.savepass"
	saved_pw=
	needs_update=true

	[ -f "$savepass" ] && {
		saved_pw=$(cat "$savepass")
		[ "X$saved_pw" = "X$hashed_pw" ] && needs_update=false
	}

	$needs_update && {
		echo -e "\n  root password changed/new, updating ...\n"

		/etc/init.d/$mysql_init stop || stop_temp_server

		start_temp_server

		version=$(dpkg -l mariadb-server | tail -1 | cut -d' ' -f4 | sed -e 's/^1://')
		release=$(echo "$version" | cut -d'.' -f1)
		subver=$(echo "$version" | cut -d'.' -f2)

		echo "  mariadb version: $version (rel $release, subver $subver)"

		# 2023-08-30
		# che due maroni ... possibile che alla questione "come impostare la password di root E avere
		# anche un accesso unix_socket" si trovino mille risposte in contraddizione tra loro?
		#
		# prima di tutto, dalla versione 10.4 (esclusa o inclusa?) e` cambiata la table mysql.user,
		# che ora non contiene piu` tutti i dati relativi all'utente, ora esiste anche mysql.global_priv;
		# da quanto leggo non e` piu` quindi possibile usare "UPDATE mysql.user" per modificare una
		# password, ma occore usare "ALTER USER"
		#
		# ps: nella global_priv il payload e` un json (dio ma che schifo) che contiene, tra le altre
		# cose, il token "auth_or" impostato su unix_socket (vedi query aggiuntiva sotto, commentata
		# perche` apparentemente sui sistemi fresh installed questa cosa e` gia` a posto, mentre io
		# l'ho dovuta forzare su un db esistente, migrato da un vecchio mysql (che poi non ne sono
		# neanche sicuro, con tutte i tentativi fatti)
		#
		# di sicuro c'e` che la versione 10.5 e` dichiarata bacata da molti
		# 
		if [ $release -ge 10 -o $subver -ge 4 ]
		then
			echo "  set root password using ALTER USER"
			set_pass_query="ALTER USER 'root'@'localhost' IDENTIFIED VIA unix_socket 
    				OR mysql_native_password USING PASSWORD('$rootpw');
			"
		else
			echo "  set root password using UPDATE mysql.user"
			# why authentication_string instead of password?
			#
			#set_pass_query="UPDATE mysql.user SET authentication_string = PASSWORD('$rootpw')
				#WHERE User = 'root' AND Host = 'localhost';"
			set_pass_query="UPDATE mysql.user SET password = PASSWORD('$rootpw')
				WHERE User = 'root' AND Host = 'localhost';"
		fi

		do_query "FLUSH PRIVILEGES; $set_pass_query"

		## this query set the local access to SOCKET (taken from mariadb-secure-installation)
		##
		##set_local_access_query="UPDATE mysql.global_priv
			##SET priv=json_set(priv,
			  ##'$.password_last_changed', UNIX_TIMESTAMP(),
			  ##'$.plugin', 'mysql_native_password',
			  ##'$.authentication_string', 'invalid',
			  ##'$.auth_or', json_array(json_object(), json_object('plugin', 'unix_socket')))
			##WHERE User='root';"

		##getconfirm mysql.set_localsock && {
			##stop_temp_server
			##start_temp_server
			##do_query "FLUSH PRIVILEGES; $set_local_access_query"
		##}

		stop_temp_server
		echo "$hashed_pw" >"$savepass"

		sleep 10
		/etc/init.d/$mysql_init start
		restart_needed=false
	}
else
	rootpw=$(jtconf mysql.root_pw)	|| exit_missing_define mysql.root_pw
	oldpw=$(ku-debconf-get mysql-server/root_password 2>/dev/null) || :
	restart_needed=true

	[ "$oldpw" != "$rootpw" ] && {

		real_pkg=$(dpkg -l mysql-server'*' | grep '^ii ' | grep 'mysql-server-[0-9]' \
			| sed -e 's/^ii  //' -e 's/ .*//')

		echo "  setting root password in debconf database for $real_pkg"
		ku-debconf-set mysql-server/root_password "$rootpw" || exit $?
		ku-debconf-set mysql-server/root_password_again "$rootpw" || exit $?

		echo "  reconfiguring $real_pkg"
		dpkg-reconfigure -fnoninteractive $real_pkg || exit $?

		# do not trig restart again
		restart_needed=false

		# re-saves actual password, because dpkg-reconfigure wipes out it
		ku-debconf-set mysql-server/root_password "$rootpw" || exit $?
	}

	# must be upgraded?
	#
	#mysql_upgrade -p$rootpw || exit $?

fi # has_mariadb





# abilita log su file? (x debug)
#
file="ku-enable-log.cnf"
if getconfirm mysql.enable_log
then
	installfile $file $mysql_confdir/
else
	[ -f $mysql_confdir/$file ] && {
		rm -f $mysql_confdir/$file
		SOMETHING_CHANGED=true
	}
fi


# abilita innodb?
#
file="ku-noinnodb.cnf"
if ! getconfirm mysql.enable_innodb
then
	installfile $file $mysql_confdir/
else
	[ -f $mysql_confdir/$file ] && {
		rm -f $mysql_confdir/$file
		SOMETHING_CHANGED=true
	}
fi


# tmpdir
#
[ -d $mysql_tmpdir ] || {
	create_dir $mysql_tmpdir mysql:mysql || exit $?
	SOMETHING_CHANGED=true
}

# datadir
#
installfile ku-datadir.cnf $mysql_confdir/ root:root 640

[ -d $mysql_datadir ] || {
	create_dir $mysql_datadir mysql:mysql || exit $?

	echo "  copying initial configuration to datadir"
	/etc/init.d/$mysql_init stop || :
	(cd /var/lib/mysql ; tar cf - . | tar xf - -C $mysql_datadir/.)

	SOMETHING_CHANGED=true
}

$DISTRIB_HAS_APPARMOR && {
	installfile "usr.sbin.mysqld" /etc/apparmor.d/ root:root 664

	# local apparmor settings file
	#
	file=usr.sbin.mysqld
	dir=/etc/apparmor.d/local

	[ -f $dir/$file ] || {
		installfile "${file}-local" $dir/$file root:root 664 || exit $?
	}
}



$SOMETHING_CHANGED && {
	$restart_needed && {
		reload_apparmor_profile usr.sbin.mysqld
		restart_service ${mysql_init} ${mysql_init}d || exit 1
	}
}


exit 0
