#!/bin/sh
#
# Clone test script for MySQL 8.0.17+ to be used with
# dbdeployer.
#
# testing if max_allowed_packet and clone_buffer_size values may
# interact badly.

set -e

cleanup () {
	local rc=$?

	if [ $rc != 0 ]; then
		msg "Script failed, returning $rc"
	else
		msg "Script completed successfully"
	fi
}

msg () {
	echo "[$(date +%H:%M:%S)] ==> $@"
}

clone_instance () {
	local db_user="$1"
	local server_port="$2"
	local db_pass="$3"

	echo "CLONE INSTANCE FROM $db_user@127.0.0.1:$server_port IDENTIFIED BY '$db_pass'"
}

# get the state for the given $use value
get_clone_state () {
        local use="$1"

        # return state from the p_s table. Only works on the destination box.

        $use -BNe "SELECT state FROM performance_schema.clone_status" 2>/dev/null || true
}

# Wait up to $sleep_delay for server to come up after cloning completes.
# - we need the server to be up, reachable, and the clone process to be signalled as completed
# - convert the "use" setting to a "status" setting
wait_for_clone_completion () {
        local use="$1"
        local sleep_delay="$2"
        local count=0
        local wanted_state=Completed
        local current_state=$(get_clone_state "$use")
        # msg "current_state: $current_state"
        while [ "$current_state" != $wanted_state ]; do
                sleep 1
                count=$(($count + 1))
                if [ $count != $sleep_delay ]; then
                        current_state=$(get_clone_state "$use")
                        # msg "current_state: $current_state"
                fi
        done
        if [ "$current_state" != $wanted_state ]; then
                msg "wait_for_clone_completion $use failed after $sleep_delay second(s). current_state: '$current_state', expecting '$wanted_state'"
                exit 1
        fi
}


# wait up to $sleep_delay for server to come up.
# - convert the "use" setting to a "status" setting
wait_for () {
	local use="$1"
	local sleep_delay="$2"
	local status=$(echo "$use" | sed -e 's/use$/status/')
	local count=0
	local current_status=$($status)
	while [ "${current_status}_${count}" != off_${sleep_time} ]; do
		sleep 1
		count=$(($count + 1))
		current_status=$($status)
	done
	if [ "$current_status" = off ]; then
		msg "wait_for $use failed after $sleep_time second(s)"
		exit 1
	fi
}

trap cleanup 0 1 2 3 9 15

sleep_delay=5
db_user=db_user
db_pass=db_pass
mysql_version=8.0.17
server1=~/sandboxes/server1_8_0_17/use
server1_port=18001
server2=~/sandboxes/server2_8_0_17/use
server2_port=18002
show_gtid_executed="select @@global.port, @@global.gtid_executed"
common_config="--master --db-password=$db_pass --db-user=$db_user --gtid --enable-general-log"
install_clone_plugin="install plugin clone soname 'mysql_clone.so'"

msg "server1 has port $server1_port, server2 has port $server2_port, gtid_mode: ON"

msg "building empty server1"
dbdeployer deploy single $mysql_version --sandbox-directory=server1_8_0_17 --port=$server1_port $common_config
msg "building empty server2"
dbdeployer deploy single $mysql_version --sandbox-directory=server2_8_0_17 --port=$server2_port $common_config

# Change to the directory containing test_db (https://github.com/datacharmer/test_db)
cd ~/data/employees

msg "populating server1 with data"
$server1 -vvvt -e "$install_clone_plugin"
$server1 < employees.sql
$server1 -vvvt -e "$show_gtid_executed"

# set some odd settings on server1 to see if clone_buffer_size can interact with max_allowed_packet
$server1 -vvvt -e 'SET GLOBAL MAX_ALLOWED_PACKET = 1024 * 1024';
$server2 -vvvt -e 'SET GLOBAL MAX_ALLOWED_PACKET = 1024 * 1024';
$server1 -vvvt -e 'SET GLOBAL CLONE_BUFFER_SIZE = 64 * 1024 * 1024';

msg "cloning server2 from server1"
$server2 -vvvt -e "$install_clone_plugin"
$server2 -vvvt -e "set persist clone_valid_donor_list='127.0.0.1:$server1_port'"
$server2 -vvvt -e "$(clone_instance $db_user $server1_port $db_pass)"

# expect an error here.

exit
#sleep $sleep_delay
sleep 5wait_for "$server2" $sleep_delay
$server2 -e "$show_gtid_executed"

