#!/bin/bash

function check_docker_install_status() {
    log_info "[$ip] Check docker.service install status."
    ssh root@${ip} "docker --version &>/dev/null" || DOCKER_INSTALL_STATUS=1
    ssh root@${ip} "cat /etc/group | awk -F ":" '{print \$1}' | grep docker" && DOCKER_INSTALL_STATUS=0 || DOCKER_INSTALL_STATUS=1
}

function check_docker_run_status() {
    log_info "[$ip] Check docker.service is running or not."
    ssh root@${ip} "systemctl status docker | grep running &>/dev/null" || DOCKER_RUN_STATUS=1
}

function config_daemon_json() {
    DAEMON_FILE=Template/daemon.json.temp
    if [ -f "${DAEMON_FILE}" ]; then
        sed -i /bip/d "${DAEMON_FILE}"
        sed -i "1a\"bip\": \"${DOCKER0_NETWORK}\"," ${DAEMON_FILE}
        sed -i /default-address-pools/d ${DAEMON_FILE}
        sed -i "2a\"default-address-pools\": [{\"base\":\"${DOCKER_GWBRIDGE_NETWORK}\",\"size\":24}]," ${DAEMON_FILE}
        sed -i /data-root/d ${DAEMON_FILE}
        sed -i "3a\"data-root\": \"${DOCKER_DATA_ROOT}\"," ${DAEMON_FILE}
        sed -i /^$/d ${DAEMON_FILE}
        NUM=$(($(wc -l ${DAEMON_FILE} | awk '{print $1}') - 1))
        sed -i "${NUM}s/\,$//g" ${DAEMON_FILE}
    else
        cat >${DAEMON_FILE} <<EOF
{
    "insecure-registries": ["192.168.251.150","192.168.251.78"],
    "bip": "${DOCKER0_NETWORK}",
    "default-address-pools": [{"base":"${DOCKER_GWBRIDGE_NETWORK}","size":24}],
    "data-root": "${DOCKER_DATA_ROOT}"
}
EOF
    fi
}

function docker_ce_install() {
    # scp Install_Packages/docker-ce/* root@${ip}:/usr/bin/
    # scp Install_Packages/system/* root@${ip}:/usr/lib/systemd/system/
    # config_daemon_json
    ssh root@${ip} "mkdir -p /etc/docker"
    scp Template/daemon.json.temp root@${ip}:/etc/docker/daemon.json

    scp Install_Packages/docker-*.rpm root@${ip}:/tmp/
    ssh root@${ip} rpm -ivh /tmp/docker-*.rpm
    ssh root@${ip} chmod +x /usr/bin/docker*
    if [ $? -ne 0 ]; then
        log_error "docker install failed !!!"
        exit 1
    else
        log_info "docker install success !!!"
        ssh root@${ip} rm -rf /tmp/docker-*.rpm
    fi
    
    ssh root@${ip} "systemctl enable docker && systemctl start docker"
}

function docker_swarm_init() {
    ssh root@${ip} docker swarm leave --force &>/dev/null
    ssh root@${ip} docker swarm init --advertise-addr=${ip} &>/dev/null
    ssh root@${ip} docker swarm join-token manager | grep "docker swarm join" >docker-swarm-join-manager.sh
    ssh root@${ip} docker swarm join-token worker | grep "docker swarm join" >docker-swarm-join-worker.sh
}

function docker_swarm_join_manager() {
    scp docker-swarm-join-manager.sh root@$ip:/tmp/docker-swarm-join-manager.sh
    ssh root@${ip} docker swarm leave --force &>/dev/null
    ssh root@${ip} "sh /tmp/docker-swarm-join-manager.sh"
    ssh root@${ip} "rm -rf /tmp/docker-swarm-join.sh"
}

function docker_swarm_join_worker() {
    scp docker-swarm-join-worker.sh root@$ip:/tmp/docker-swarm-join-worker.sh
    ssh root@${ip} docker swarm leave --force &>/dev/null
    ssh root@${ip} "sh /tmp/docker-swarm-join-worker.sh"
    ssh root@${ip} "rm -rf /tmp/docker-swarm-join-worker.sh"
}

function docker_swarm_config() {
    local ip=
    for ((i = 0; i < ${#MANAGER_IP[@]}; i++)); do
        ip=${MANAGER_IP[i]}
        if [ ${i} -eq 0 ]; then
            log_info "[$ip]: Starting docker swarm init"
            docker_swarm_init
        else
            if [ -n "${ip}" ]; then
                log_info "[$ip] Join docker swarm cluster as manager"
                docker_swarm_join_manager
            fi
        fi
        unset ip
    done

    for ip in ${WORKER_IP[@]}; do
        log_info "docker swarm cluster join as worker: $ip"
        docker_swarm_join_worker
    done
    unset ip
}

function get_nodeid_by_ip() {
    local IP
    for node in $(ssh ${DEPLOYED_MANAGER} "docker node ls | awk 'NR!=1{print \$1}'"); do
        IP=$(ssh ${DEPLOYED_MANAGER} "docker node inspect ${node} --format {{.Status.Addr}}")
        if [ "$IP" == $1 ]; then
            echo "${node}"
        else
            continue
        fi
    done
}

# 数组倒序
function revers() {
    i=0
    len=${#MIDDLEWARE_CLUSTER_NODE[@]}

    while [ $i -lt $len ]; do
        tmp=${MIDDLEWARE_CLUSTER_NODE[i]}
        arr[i]=${MIDDLEWARE_CLUSTER_NODE[$len - 1]}
        arr[$len - 1]=$tmp
        let i++ len--
    done
}

function config_weboffice_labels() {
    if [ ${#INDRIVE_NODE[@]} -eq 1 ];then
        ssh ${DEPLOYED_MANAGER} "docker node update --label-add weboffice=true ${NODEID}"
    else
        ssh ${DEPLOYED_MANAGER} "docker node update --label-add weboffice=true ${INDRIVE_NODE_0_ID}"
    fi
}

function config_svc_labels() {
    # if [ "${MIDDLEWARE_MODE}" == "standalone" ] && [ "${MIDDLEWARE_STANDALONE_HA}" == "true" ] && [ "${#IP_LIST[@]}" -gt 1 ]; then
    #     log_info "MIDDLEWARE_MODE is standalone, MIDDLEWARE_DATA_PATH must be shared storage, check it now."
    #     check_share_storage ${MIDDLEWARE_DATA_PATH}
    # fi
    INDRIVE_NODE_0_ID=$(get_nodeid_by_ip ${INDRIVE_NODE[0]})
    for IP in ${IP_LIST[@]}; do
        SVC_LIST=$(get_node_attribute ${REGION} ${IP} svc | tr ',' ' ')
        NODEID=$(get_nodeid_by_ip $IP)
        if [ -z ${NODEID} ]; then
            log_error "${IP}: Get nodeid failed"
        fi
        for svc in ${SVC_LIST}; do
            if [ ${svc} == "weboffice" ]; then
                config_weboffice_labels
            else
                log_info "${IP}: Update service label ${svc}=true"
                ssh ${DEPLOYED_MANAGER} "docker node update --label-add ${svc}=true $NODEID"
                ssh ${DEPLOYED_MANAGER} "docker node update --label-add nodeportainer=Portainer $NODEID"
            fi
        done
        log_info "${IP} [${NODEID}]: Node label config complete."
    done
}

function config_node_labels() {
    for _ip in ${IP_LIST[@]}; do
        local nodeid=$(get_nodeid_by_ip $_ip)
        log_info "[${_ip}] [$nodeid]: Update node labels: nodetype=Portainer"
        ssh ${DEPLOYED_MANAGER} "docker node update --label-add nodeportainer=Portainer ${nodeid}"
    done

    for _ip in ${INDRIVE_NODE[@]}; do
        NODEID=$(get_nodeid_by_ip ${_ip})
        log_info "[${_ip}] [$NODEID]: Update node labels: nodetype=InDrive"
        ssh ${DEPLOYED_MANAGER} "docker node update --label-add nodetype=InDrive ${NODEID}"
        log_success "[${_ip}] [$NODEID]: Update node labels nodetype=InDrive complete"
    done

    for _ip in ${APM_NODE[@]}; do 
        NODEID=$(get_nodeid_by_ip ${_ip})
        log_info "[${_ip}] [$NODEID]: Update node labels: isapm=true"
        ssh ${DEPLOYED_MANAGER} "docker node update --label-add isapm=true ${NODEID}"
        log_success "[${_ip}] [$NODEID]: Update node labels isapm=true complete"
    done

    if [ "${MIDDLEWARE_MODE}" == "standalone" ]; then
        for _ip in ${MIDDLEWARE_NODE[@]}; do
            NODEID=$(get_nodeid_by_ip ${_ip})
            log_info "[${_ip}] [$NODEID]: Update node label: nodelabels=Middleware"
            ssh ${DEPLOYED_MANAGER} "docker node update --label-add nodelabels=Middleware ${NODEID}"
            log_success "[${_ip}] [$NODEID]: Update node labels nodelabels=Middleware complete"
        done
    fi

    if [ "${MIDDLEWARE_MODE}" == "cluster" ]; then
        declare -a MIDDLEWARE_CLUSTER_NODE

        for _ip in ${MIDDLEWARE_NODE[@]}; do
            NODEID=$(get_nodeid_by_ip ${_ip})
            MIDDLEWARE_CLUSTER_NODE[${#MIDDLEWARE_CLUSTER_NODE[@]}]=${NODEID}
        done

        revers

        if [ ${#MIDDLEWARE_NODE[@]} -ne 3 ]; then
            log_error "The nodes which contain Middleware label not match 3"
            exit 3
        fi

        for ((i = 0; i <= 2; i++)); do
            for node in ${MIDDLEWARE_CLUSTER_NODE[@]}; do
                for MID in mysql redis rabbitmq es; do
                    if [ "${MID}" = "mysql" ]; then
                        log_info "[$node]: Update node label ${MID}labels=${MID}${i}"
                        ssh ${DEPLOYED_MANAGER} docker node update --label-add ${MID}labels=${MID}${i} ${node}
                        log_success "[$node] Update node label ${MID}labels=${MID}$((${i})) complete"
                    else
                        log_info "[$node]: Update node label ${MID}labels=${MID}$((${i} + 1))"
                        ssh ${DEPLOYED_MANAGER} docker node update --label-add ${MID}labels=${MID}$((${i} + 1)) ${node}
                        log_success "[$node] Update node label ${MID}labels=${MID}$((${i} + 1)) complete"
                    fi
                done
                unset MIDDLEWARE_CLUSTER_NODE[i]
            done
        done
    fi
    unset MIDDLEWARE_CLUSTER_NODE
}

function overlay_network_create() {
    ssh ${DEPLOYED_MANAGER} "docker network ls |grep macrowing &> /dev/null || docker network create --driver overlay macrowing --subnet ${MACROWING_NETWORK}"
}

function docker_install() {
    config_daemon_json
    for ip in ${IP_LIST[@]}; do
        check_docker_install_status
        if [ "${DOCKER_INSTALL_STATUS}" == 1 ]; then
            log_info "$ip install docker-ce"
            docker_ce_install
            unset DOCKER_INSTALL_STATUS
        else
            log_warning "[$ip]  Docker is already installed."
            log_error "In order to achieve the desired effect,please run scripts/uninstall.sh to uninstall docker."
            exit 1
        fi
        check_docker_run_status
        if [ "${DOCKER_RUN_STATUS}" == 1 ]; then
            ssh root@${ip} systemctl enable docker
            ssh root@${ip} systemctl start docker
            unset DOCKE_RUN_STATUS
        fi
    done
    docker_swarm_config
    config_svc_labels
    config_node_labels
    overlay_network_create
}
