#!/bin/bash

#set -x

. `dirname $0`/functions

THIS_SCRIPT_NAME="`basename $0`"
if [ $# -lt 2 ]; then
    write_switch_log "The $THIS_SCRIPT_NAME, the required parameters are missing. \
The current parameters are ($*)."
    exit 1
fi

NOTIFY_TYPE="$1"
ROUTER_ID="$2"

try_reverse_replication () {
    local script_name="$THIS_SCRIPT_NAME"
    local reconfig_script_path="$BEST_PRACTICE_PATH/reconfig_normal.sh"

    local rc=
    local result=
    local sleep_time=${REVERSE_REPLICATION_FAIL_DELAY:=10}

    for i in `seq 1 ${REVERSE_REPLICATION_RETRY_COUNT:=90}`; do
        local ip_address="`get_available_ip_address`"
        if [ -n "$ip_address" ]; then
            write_switch_log "The $script_name, start try reverse replication to the \
remote($ip_address), pid($$)."

            check_remote_db_is_active "$script_name" "$ip_address"
            if [ $? -eq 0 ]; then
                write_switch_log "The $script_name, database service is active on remote \
host($ip_address)."

                write_switch_log "The $script_name, try to execute \
'$reconfig_script_path $THIS_HOST_NAME' command on the remote host($ip_address)."
                result=`ssh_execute_cmd $PEER_HOST_USER_NAME@$ip_address "$reconfig_script_path $THIS_HOST_NAME"`
                rc=$?
                if [ $rc -eq 0 ]; then
                    write_switch_log "The $script_name, $reconfig_script_path \
$THIS_HOST_NAME successfully executed on peer host($ip_address), result($result), pid($$)."
                    return 0
                else
                    write_switch_log "The $script_name, $reconfig_script_path \
$THIS_HOST_NAME failed on ($ip_address).ec($rc),result($result), pid($$)"
                    sleep $sleep_time
                fi
            else
                write_switch_log "The $script_name, database service is not active \
on remote host($ip_address)."
                sleep $sleep_time
            fi
        else
            write_switch_log "The $script_name, there is no IP address in \
($PEER_HOST_ADDRESS_LIST) that can be successfully connected."
            sleep $sleep_time
        fi

        write_switch_log "The $script_name, the current $i attempt to start \
reverse replication. maximum retries: $REVERSE_REPLICATION_RETRY_COUNT. pid($$)"
    done

    write_switch_log "The $script_name, After $REVERSE_REPLICATION_RETRY_COUNT attempts, \
the peer host($ip_address) still failed to establish a slave relationship."
    return 1
}

notify_master () {
    local router_id="$1"
    local script_name="$THIS_SCRIPT_NAME"
    local result=
    local slave_state=

    write_switch_log "The notify_master function is called by keepalived router_id($router_id)."

    local ip_address="`get_available_ip_address`"
    if [ -n "$ip_address" ]; then
        result=`ssh_execute_cmd "$PEER_HOST_USER_NAME@$ip_address" 'systemctl stop dbackup3-backupd'`
        if [ $? -ne 0 ]; then
            write_switch_log "The $script_name, remote($ip_address) systemctl stop dbackup3-backupd error($result)."
        fi
    else
        write_switch_log "The $script_name, there is no IP address in \
($PEER_HOST_ADDRESS_LIST) that can be successfully connected."
    fi

    local sleep_time=${WAIT_BINLOG_DELAY:=1}
    while true; do
        result=`local_db_execute_query "SHOW SLAVE STATUS\G" false`
        if [ $? -eq 0 ]; then
            if [ -z "$result" ]; then
                write_switch_log "The $script_name, No slave status available. Exiting..."
                break
            fi

            slave_state=$(echo "$result" | grep "Slave_SQL_Running_State:" | awk -F': ' '{print $2}')

            # Check if Slave_SQL_Running_State is the specified state
            if [ -z "$slave_state" ]; then
                write_switch_log "The $script_name, Slave_SQL_Running_State is null, result: $result."
                break
            fi

            check_relay_all_log "$slave_state"
            if [ $? -eq 0 ]; then
                write_switch_log "The $script_name, Binlog has been fully applied. State: $slave_state"
                break
            else
                write_switch_log "The $script_name, Current state: $slave_state. \
Waiting for binlog to be applied..."
                sleep $sleep_time
            fi
        else
            write_switch_log "The $script_name, the SQL statement \
SHOW SLAVE STATUS fails to be executed on the local database server, Retry after $sleep_time seconds."
            sleep $sleep_time
        fi
    done

    # Unlocking tables and stopping replication
    local stop_slave_sql="unlock tables; stop slave; reset slave all; flush privileges;"
    result=`local_db_execute_query "$stop_slave_sql" true`
    if [ $? -ne 0 ]; then
        write_switch_log "The $script_name, when notify_master is called, \
statement $stop_slave_sql fails to execute on the local database server."
        return
    fi

    write_switch_log "The $script_name, mysql unlock, change to master sucess."

    # Start Reverse Replication
    try_reverse_replication
    write_switch_log "The $script_name, reverse replication step execution completed."

    start_keepalived_service
    start_backupd
    write_switch_log "The $script_name, start dbackup3-backupd and \
dbackup3-keepalived successfully when calling notify_master."

}

notify_fault () {
    local router_id="$1"
    local script_name="$THIS_SCRIPT_NAME"
    local result=
    local log_msg=

    write_switch_log "The notify_fault function is called by keepalived router_id($router_id)."

    result=`local_db_execute_query "SHOW SLAVE STATUS\G" false`
    if [ $? -ne 0 ]; then
        log_msg="The $script_name, Execution of the SQL statement SHOW SLAVE STATUS \
failed on local database service."
        write_switch_log "$log_msg"
        return
    fi

    if [ -n "$result" ]; then
        log_msg="The local database service is currently a slave node and Nothing to do."
        write_switch_log "$log_msg"
        return
    fi

    stop_backupd
}

notify_stop () {
    local router_id="$1"
    local script_name="$THIS_SCRIPT_NAME"
    local result=
    local log_msg=

    write_switch_log "The notify_stop function is called by keepalived router_id($router_id)."

    result=`local_db_execute_query "SHOW SLAVE STATUS\G" false`
    if [ $? -ne 0 ]; then
        log_msg="The $script_name, Execution of the SQL statement SHOW SLAVE STATUS \
failed on local database service."
        write_switch_log "$log_msg"
        return
    fi

    if [ -n "$result" ]; then
        log_msg="The local database service is currently a slave node and Nothing to do."
        write_switch_log "$log_msg"
        return
    fi

    stop_backupd
}


write_switch_log "This $THIS_SCRIPT_NAME is called with the parameter ($*)."

if [ "$NOTIFY_TYPE" = "master" ]; then
    nohup `notify_master "$ROUTER_ID"` &
    BG_PID=$!
    write_switch_log "The $THIS_SCRIPT_NAME, start notify_master in the background, pid($BG_PID)."
fi

if [ "$NOTIFY_TYPE" = "fault" ]; then
    notify_fault "$ROUTER_ID"
fi

if [ "$NOTIFY_TYPE" = "stop" ]; then
    notify_stop "$ROUTER_ID"
fi

write_switch_log "This $THIS_SCRIPT_NAME is executed and the parameters are ($*)."
exit 0
