#!/bin/sh

# Database credentials can be provided via environment variables:
# - WP_CLI_TEST_DBHOST is the host to use and can include a port or a socket after a colon, i.e "127.0.0.1:33060" (defaults to "localhost")
# - WP_CLI_TEST_DBROOTUSER is the user that has permission to administer databases and users (defaults to "root").
# - WP_CLI_TEST_DBROOTPASS is the password to use for the above user (defaults to an empty password).
# - WP_CLI_TEST_DBNAME is the database that the tests run under (defaults to "wp_cli_test").
# - WP_CLI_TEST_DBUSER is the user that the tests run under (defaults to "wp_cli_test").
# - WP_CLI_TEST_DBPASS is the password to use for the above user (defaults to "password1").

# POSIX compliant function to check if a string is numeric.
is_numeric() {
    case $1 in
        ''|*[!0-9]*) return 1;;  # returns 1 if not numeric
        *) return 0;;           # returns 0 if numeric
    esac
}

HOST=localhost
PORT=""
HOST_STRING=''
if [ -n "${WP_CLI_TEST_DBHOST}" ]; then
	case ${WP_CLI_TEST_DBHOST##*[]]} in
		(*:*) HOST=${WP_CLI_TEST_DBHOST%:*} PORT=${WP_CLI_TEST_DBHOST##*:};;
		(*)   HOST=${WP_CLI_TEST_DBHOST};;
	esac
	HOST_STRING="-h${HOST}"
	if [ -n "${PORT}" ]; then
		# If the port is not numeric, then we assume it is a socket path.
		if is_numeric "${PORT}"; then
			HOST_STRING="${HOST_STRING} --port=${PORT} --protocol=tcp"
		else
			HOST_STRING="${HOST_STRING} --socket=${PORT} --protocol=socket"
		fi
	fi
fi

USER=root
if [ -n "${WP_CLI_TEST_DBROOTUSER}" ]; then
  USER="${WP_CLI_TEST_DBROOTUSER}"
fi

PASSWORD_STRING=""
if [ -n "${WP_CLI_TEST_DBROOTPASS}" ]; then
  PASSWORD_STRING="-p${WP_CLI_TEST_DBROOTPASS}"
fi

TEST_DB=wp_cli_test
if [ -n "${WP_CLI_TEST_DBNAME}" ]; then
  TEST_DB="${WP_CLI_TEST_DBNAME}"
fi

TEST_USER=wp_cli_test
if [ -n "${WP_CLI_TEST_DBUSER}" ]; then
  TEST_USER="${WP_CLI_TEST_DBUSER}"
fi

TEST_PASSWORD=password1
if [ -n "${WP_CLI_TEST_DBPASS}" ]; then
  TEST_PASSWORD="${WP_CLI_TEST_DBPASS}"
fi

echo 'Checking if MySQL is ready...'
while ! mysql ${HOST_STRING} --user="${USER}" "${PASSWORD_STRING}" --execute="SHOW DATABASES;" | grep 'information_schema' >/dev/null;
do
  echo 'Waiting for MySQL...'
  sleep 5
  i=$((i+1))
  if [ $i -gt 36 ]; then
	echo 'MySQL failed to start. Aborting.'
	exit 1
  fi
done

# Prepare the database for running the tests with a MySQL version 8.0 or higher.
install_mysql_db_8_0_plus() {
	set -ex
	mysql -e "CREATE DATABASE IF NOT EXISTS \`${TEST_DB}\`;" ${HOST_STRING} -u"${USER}" "${PASSWORD_STRING}"
	mysql -e "CREATE USER IF NOT EXISTS \`${TEST_USER}\`@'%' IDENTIFIED WITH caching_sha2_password BY '${TEST_PASSWORD}'" ${HOST_STRING} -u"${USER}" "${PASSWORD_STRING}"
	mysql -e "GRANT ALL PRIVILEGES ON \`${TEST_DB}\`.* TO '${TEST_USER}'@'%'" ${HOST_STRING} -u"${USER}" "${PASSWORD_STRING}"
	mysql -e "GRANT ALL PRIVILEGES ON \`${TEST_DB}_scaffold\`.* TO '${TEST_USER}'@'%'" ${HOST_STRING} -u"${USER}" "${PASSWORD_STRING}"
}

# Prepare the database for running the tests with a MySQL version lower than 8.0.
install_mysql_db_lower_than_8_0() {
	set -ex
	mysql -e "CREATE DATABASE IF NOT EXISTS \`${TEST_DB}\`;" ${HOST_STRING} -u"${USER}" "${PASSWORD_STRING}"
	mysql -e "GRANT ALL ON \`${TEST_DB}\`.* TO '${TEST_USER}'@'%' IDENTIFIED BY '${TEST_PASSWORD}'" ${HOST_STRING} -u"${USER}" "${PASSWORD_STRING}"
	mysql -e "GRANT ALL ON \`${TEST_DB}_scaffold\`.* TO '${TEST_USER}'@'%' IDENTIFIED BY '${TEST_PASSWORD}'" ${HOST_STRING} -u"${USER}" "${PASSWORD_STRING}"
}

VERSION_STRING=$(mysql -e "SELECT VERSION()" --skip-column-names ${HOST_STRING} -u"${USER}" "${PASSWORD_STRING}")
VERSION=$(echo "${VERSION_STRING}" | grep -o '^[^-]*')
MAJOR=$(echo "${VERSION}" | cut -d. -f1)
MINOR=$(echo "${VERSION}" | cut -d. -f2)
TYPE="MySQL"
case "${VERSION_STRING}" in
	*"MariaDB"*)
		TYPE="MariaDB"
		;;
esac

echo "Detected ${TYPE} at version ${MAJOR}.${MINOR}"


if [ "${TYPE}" != "MariaDB" ] && [ "${MAJOR}" -ge 8 ]; then
	install_mysql_db_8_0_plus
else
	install_mysql_db_lower_than_8_0
fi
