#!/bin/bash

DEFAULT_BACKUP_FOLDER="$HOME/RECOVERY_MARIADB"

confirm() {
	read -rp "$1 ([y]es or [N]o): "
	case $(echo "$REPLY" | tr '[:upper:]' '[:lower:]') in
	y | yes) echo "yes" ;;
	*) echo "no" ;;
	esac
}

synopsis() {
	echo "usage: "
	printf "\t list | console | connections\n"
	printf "\t ---------------------------\n"
	printf "\t use <DB_NAME>\n"
	printf "\t create <DB_NAME> [PASSWORD]\n"
	printf "\t ---------------------------\n"
	printf "\t backup <DB_NAME> [FOLDER]\n"
	printf "\t restore <DB_NAME> <FILE>\n"
	printf "\t ---------------------------\n"
	printf "\t rename <DB_NAME> <NEW_NAME>\n"
}

list() {
	lxc exec ct1 -- sh -c "echo \"SELECT schema_name FROM information_schema.schemata where schema_name not in ('information_schema','mariadb','mysql','performance_schema')\" | mariadb -u root --skip-column-names -r "
}

console() {
	if [[ -z $1 ]]; then
		lxc exec ct1 -- mariadb -u root
	else
		lxc exec ct1 -- sh -c "echo \"$1\" | mariadb -u root"
	fi
}

connections() {
	lxc exec ct1 -- sh -c "echo \"select id, user, host, db, command, time, state, info, progress from information_schema.processlist\" | mariadb -u root "
}

use() {
	lxc exec ct1 -- mariadb -u root "$DB_NAME"
}

create() {

	# shellcheck disable=SC1091
	source /opt/miaou-bash/lib/functions.sh

	# shellcheck disable=SC2034
	mapfile -t DBs < <(list)

	local NEW_DB="${1:-$DB_NAME}"
	local NEW_PASSWORD="${2:-$NEW_DB}"

	if ! containsElement DBs "$NEW_DB"; then
		lxc exec ct1 -- sh -c "echo \"\
		CREATE DATABASE \\\`$NEW_DB\\\`; \
		GRANT ALL ON \\\`$NEW_DB\\\`.* TO \\\`$NEW_DB\\\`@'%' IDENTIFIED BY '$NEW_PASSWORD'; \
		FLUSH PRIVILEGES; \
		\" | mariadb -u root"
	else
		echo "$NEW_DB already exists!"
	fi
}

backup() {

	if [[ ! -d "$FOLDER" ]]; then
		echo "error: Folder required!"
		file "$FOLDER"
		exit 2
	fi

	mkdir -p "$FOLDER"
	DATE=$(date '+%F')
	ARCHIVE="$FOLDER"/$DB_NAME-$DATE.mariadb.gz

	if [[ -f $ARCHIVE ]]; then
		VERSION_CONTROL=numbered mv -b "$ARCHIVE" "$FOLDER"/"$DB_NAME"-"$DATE"-daily.mariadb.gz
	fi

	echo "backup $DB_NAME into $FOLDER"
	mariadb-dump -h ct1.lxd -u "$DB_NAME" -p"$DB_NAME" "$DB_NAME" | gzip >"$ARCHIVE"
	echo "archive file created: $ARCHIVE"
}

restore() {

	echo "restore $DB_NAME $FILE"
	if [[ ! -f "$FILE" ]]; then
		echo "error: Backup file (*.mariadb.gz) required!"
		file "$FILE"
		exit 2
	fi

	PROCESSES=$(lxc exec ct1 -- sh -c "echo \"select id, user, host, db, command, time, state, info, progress from information_schema.processlist\" | mariadb -u root")

	set +e
	PROCESS_COUNT=$(echo "$PROCESSES" | grep -c "$DB_NAME")
	if [[ $PROCESS_COUNT -gt 0 ]]; then
		echo "FAILURE: There are some connections to database, please consider stopping bound services"
		echo
		echo "$PROCESSES"
		exit 2
	fi
	set -e

	if [[ "yes" == $(confirm "RESTORATION will drop DATABASE, please acknowledge with care!!!") ]]; then
		if list | grep -q "$DB_NAME"; then
			echo "backup <$DB_NAME> for safety reason"
			backup
			echo "drop database <$DB_NAME>"
			lxc exec ct1 -- sh -c "echo \"DROP DATABASE \\\`$DB_NAME\\\`\" | mariadb -u root"
		fi

		echo "create <$DB_NAME>"
		create
		# lxc exec ct1 -- sh -c "CREATE DATABASE \\\`$DB_NAME\\\`\" | mariadb -u root"
		gunzip -c "$FILE" | grep -av "^CREATE DATABASE" | grep -av "^USE" | mariadb -h ct1.lxd -u "$DB_NAME" -p"$DB_NAME" "$DB_NAME"
		echo RESTORATION completed successfully

	else
		exit 1
	fi
}

rename() {
	echo "rename $DB_NAME to $NEW_NAME"
	local DB_NAME_FOUND=false
	for database in $(list); do
		if [[ $database == "$DB_NAME" ]]; then
			DB_NAME_FOUND=true
		fi
		if [[ $database == "$NEW_NAME" ]]; then
			echoerr "$NEW_NAME already exists! please provide another name instead of <$NEW_NAME> or run list command"
			exit 20
		fi
	done
	if [[ ! $DB_NAME_FOUND ]]; then
		echoerr "source <$DB_NAME> does not exist!"
		exit 20
	fi

	if [[ "$DB_NAME" == "$NEW_NAME" ]]; then
		echowarn "no need to rename; no change required <$DB_NAME>"
		exit 0
	fi

	echo "create new database <$NEW_NAME>"
	create "$NEW_NAME"

	for table in $(console "use '$DB_NAME'; show tables"); do
		if [[ $table != "Tables_in_$DB_NAME" ]]; then
			echo "renaming table \`$DB_NAME\`.$table to \`$NEW_NAME\`.$table"
			console "use '$DB_NAME'; rename table \\\`$DB_NAME\\\`.$table to \\\`$NEW_NAME\\\`.$table;"
		fi
	done

	echo "every table has been renamed, so remove old database <$DB_NAME>"
	console "drop user \\\`$DB_NAME\\\`"
	console "drop database \\\`$DB_NAME\\\`"
}

# MAIN
set -Eeuo pipefail
# shellcheck source=/dev/null
. "$MIAOU_BASEDIR/lib/functions.sh"

[[ $# -lt 1 ]] && synopsis && exit 1
ACTION=$1

case $ACTION in
console)
	shift
	TAIL=$*
	console "$TAIL"
	;;
list)
	list
	;;
connections)
	connections
	;;
use)
	[[ $# -lt 2 ]] && synopsis && exit 1
	DB_NAME=$2
	use
	;;
create)
	[[ $# -lt 2 ]] && synopsis && exit 1
	DB_NAME=$2
	DB_PASSWORD=${3:-$DB_NAME}
	create
	;;
backup)
	[[ $# -lt 2 ]] && synopsis && exit 1
	DB_NAME=$2
	FOLDER=${3:-$DEFAULT_BACKUP_FOLDER}
	backup
	;;
restore)
	[[ $# -lt 3 ]] && synopsis && exit 1
	DB_NAME=$2
	FILE=$3
	FOLDER=${4:-$DEFAULT_BACKUP_FOLDER}
	DB_PASSWORD="$DB_NAME"
	restore
	;;
rename)
	[[ $# -lt 3 ]] && synopsis && exit 1
	DB_NAME=$2
	NEW_NAME=$3
	rename
	;;
*)
	synopsis
	exit 1
	;;
esac