#!/bin/bash

# container_backup="dbbackup_`date "+%Y-%m-%d-%H%M"`"
recovery_backup_log="/tmp/recovery_backup.log"
>$recovery_backup_log

log() {
    local text;local logtype
    logtype=$1
    text=$2
    #其实可以再将日志的格式定义为一个字符串，这样就不用重复写`date +'%F %H:%M:%S'`\t$1\t$2\033[0m，又可以省好多代码。
    case $logtype in 
        error)
            echo -e "\033[31m`date +'%F %H:%M:%S'`[$1]\t$2\033[0m" | tee -a $recovery_backup_log;;
        info)
            echo -e "\033[32m`date +'%F %H:%M:%S'`[$1]\t$2\033[0m" | tee -a $recovery_backup_log;;
        warn)
            echo -e "\033[33m`date +'%F %H:%M:%S'`[$1]\t$2\033[0m" | tee -a $recovery_backup_log;;
    esac
}

# 在 MySQL 容器中执行命令
exec_on_container() {
    container_id=$(docker ps |grep mysql:v8 |awk '{print $1}')
    exec_sql="mysql -urepl -pXjb0^DDy -N -e"

    if [ "$1" == "sql" ];then
        docker exec  $container_id $exec_sql "$2"
    else
        docker exec  $container_id $*
    fi
}



# 检查 MGR 状态
check_mgr() {
    res=$(exec_on_container sql "select * from performance_schema.replication_group_members")
    health_num=$(echo $res | grep -o ONLINE |wc -l)
    if [ "$health_num" != "3" ];then
        # echo "MGR 集群异常，当前节点数量为: $health_num."
        log info "MGR cluster is unhealthy. Number of current nodes:$health_num. Start recovery..."
    else
        if [ "$ISFORCE" != "true" ];then
            # echo "MGR 集群节点状态正常，当前节点数量为: $health_num. 无需进行数据备份及恢复，如需要强制执行，使用 -f/--force 参数."
            log error "MGR cluster is healthy. Number of current nodes:$health_num. No need for data recovery, if you need to enforce it, use the -f/--force parameter."
            exit 1;
        else
            # echo "MGR 集群节点状态正常，当前节点数量为: $health_num. 强制进行数据备份."
            log warn "MGR cluster is healthy. Number of current nodes:$health_num. Force recovery!!!"
        fi
    fi
}


main() {
    #检查 Docker 启动状态
    [[ $(docker node ls) ]] && log info "docker swarm status is health." \
    || log error "docker swarm is unhealth. Please check docker status."

    # 配置 rsync 密码文件
    echo "1qaz@WSX" > /etc/recovery_db.passwd
    chmod 600 /etc/recovery_db.passwd

    # 停止本地数据库服务
    node_lables=$(docker inspect lml7d099m7qxxerl04d5fjen3  |grep mysqllabels |awk '{print $2}')
    get_lables=$(echo ${node_lables%*,} | sed 's/\"//g')
    service_name=$(docker service ls|grep $get_lables | awk '{print $2}')
    docker service scale $service_name=0 && \
    log info "Stop $service_name service."

    disk_avail=$(df -T $mysql_mount_dir |awk '{print $5}'|grep -o [0-9].*[0-9])
    backup_size=$(rsync -avz --password-file=/etc/recovery_db.passwd  -n --stats backup@$backup_host::dbbackup/tmp/dbbackup/ /tmp  | tail -1 |awk '{print $4}'|sed 's/,//g')

    # 重命名备份原数据库文件
    log info "Please wait copy remote backup to local."
    sleep 10
    if [ "$(ls -A $mysql_mount_dir)" ];then
        log info "rename $mysql_mount_dir to ${mysql_mount_dir%*/}-`date "+%Y-%m-%d-%H%M"`-bak"
        mv $mysql_mount_dir ${mysql_mount_dir%*/}-`date "+%Y-%m-%d-%H%M"`-bak
    fi



    if [ $backup_size -lt $[disk_avail*1024] ];then
        log info "Disk space is ok."
        rsync -avP --remove-source-files --password-file=/etc/recovery_db.passwd backup@$backup_host::dbbackup/tmp/dbbackup/ $mysql_mount_dir
        if [ $? = 0 ];then
            log info "Copy backup from $backup_host completed."
        else
            log error "Copy backup from $backup_host failed. Please check!"
        fi
    else
        log error "$mysql_mount_dir Not enough disk space. Free up disk space and try again."
        exit 1;
    fi

    # 恢复数据库备份
    chown -R polkitd:input $mysql_mount_dir && \
    log info "Update $mysql_mount_dir backup file privileges."

    docker service scale $service_name=1 && \
    log info "Please wait $service_name start."
    sleep 20
    exec_on_container sql "reset slave; start group_replication;" && \
    log info "mgr started successfully, please check ."

    # 检测恢复结果
    # new_res=$(exec_on_container sql "select * from performance_schema.replication_group_members")
    # health_num=$(echo $res | grep -o ONLINE |wc -l)
    # if [ "$health_num" != "3" ];then
    #     log error "MGR cluster is still unhealthy. Number of current nodes:$health_num. Please check!!!"
    # else
    #     log info "MGR cluster is healthy. Number of current nodes:$health_num."
    # fi

}

ARGS=`getopt -o d:h:f --long mysql-dir:,backup-ip:,force-recovery -n 'mgr_recovery.sh' -- "$@"`

if [ $? != 0 ]; then
    echo "Terminating..."
    exit 1
fi

eval set -- "${ARGS}"


while true
do
    case "$1" in
        -f|--force-recovery)
            ISFORCE=true
            shift
            ;;
        -d|--mysql-dir)
            mysql_mount_dir=$2;
            if [ ! -f $mysql_mount_dir ];then
                log warn "$mysql_mount_dir does not exist. Create the file $mysql_mount_dir."
                mkdir -p $mysql_mount_dir
            fi
            shift 2
            ;;
        -h|--backup-ip)
            backup_host=$2;
            shift 2
            ;;
        --)
            shift
            break
            ;;
        *)
            log error "Parameter error!"
            exit 1
            ;;
    esac
done

echo $mysql_mount_dir
if [ -z  "$mysql_mount_dir" -a -z "$backup_host" ];then
    log error "Parameter error!"
    exit 1;
fi

check_mgr
main
