#!/bin/bash

function prepare() {
    common_config_check
    node_ip_list_check
    manager_node_num_check
    subregion_config_check
    database_config_check
    ceph_config_check
    s3_config_check
    swift_config_check
    node_port_check
    hostname_check
    system_version_check
    logserver_resolver
    data_path_check
    path_mount_point_compare ${MIDDLEWARE_DATA_PATH} ${DBBACKUP_PATH}
    path_mount_point_compare ${MIDDLEWARE_DATA_PATH} ${ESBACKUP_PATH}
    storage_check
}

# @string_check
# Tools function. Check if $2 is "".
function string_check() {
    if [ -z "$2" ]; then
        log_error "check failed, please config $1 values"
        exit 1
    fi
}

# @common_config_check
# Cehck if ENVIRONMENT VARIABLE from common part is ""
function common_config_check() {
    string_check STORAGE_MODE ${STORAGE_MODE}
    string_check REGION ${REGION}
    string_check RUNENV ${RUNENV}
}

# @node_ip_list_check
# Cehck if ENVIRONMENT VARIABLE $IP_LIST and $MANAGER_IP is ""
function node_ip_list_check() {
    string_check IP_LIST ${IP_LIST}
    string_check MANAGER_IP ${MANAGER_IP}
}

# @manager_node_num_check
# Check if MANAGER number is odd.
function manager_node_num_check() {
    if [ $((${#MANAGER_IP[@]} % 2)) -eq 0 ]; then
        log_error "manager node num is ${#MANAGER_IP[@]}, 必须设置manager节点数为奇数个！！"
        exit
    fi
}

# @subregion_config_check
# Cehck if ENVIRONMENT VARIABLE from subregionconf part is ""
function subregion_config_check() {
    if [ "${REGION}" == "subregion" ]; then
        string_check REGIONNAME ${REGIONNAME}
        string_check PRIMARYURL ${PRIMARYURL}
        string_check INTRANETADDRESS ${INTRANETADDRESS}
        string_check REGIONURL ${REGIONURL}
        string_check REGISTERCODE ${REGISTERCODE}
    fi
}

# @database_config_check
# Cehck if ENVIRONMENT VARIABLE from database part is ""
function database_config_check() {
    if [ "${UsedDatabase}" == "external" ]; then
        string_check DatabaseServerName ${DatabaseServerName}
        string_check DatabaseUserName ${DatabaseUserName}
        string_check DatabasePassword ${DatabasePassword}
        string_check DatabaseServerPort ${DatabaseServerPort}
        string_check DatabaseName ${DatabaseName}
    fi
}

# @ceph_config_check
# Cehck if ENVIRONMENT VARIABLE from ceph part is ""
function ceph_config_check() {
    if [ "${STORAGE_MODE}" == "ceph" ]; then
        string_check S3SECRET ${S3SECRET}
        string_check S3ACCESS ${S3ACCESS}
        string_check S3URL ${S3URL}
        string_check S3BUCKET ${S3BUCKET}
        string_check S3HealthUrl ${S3HealthUrl}
    fi
}

# @s3_config_check
# Cehck if ENVIRONMENT VARIABLE from s3 part is ""
function s3_config_check() {
    if [ "${STORAGE_MODE}" == "s3" ]; then
        string_check S3SECRET ${S3SECRET}
        string_check S3ACCESS ${S3ACCESS}
        string_check S3URL ${S3URL}
        string_check S3BUCKET ${S3BUCKET}
    fi
}

# @swift_config_check
# Cehck if ENVIRONMENT VARIABLE from swift part is ""
function swift_config_check() {
    if [ "${STORAGE_MODE}" == "swift" ]; then
        string_check S3URL ${S3URL}
        string_check S3SECRET ${S3SECRET}
        string_check SWIFTUSERNAME ${SWIFTUSERNAME}
        string_check CONTAINERID ${CONTAINERID}
    fi
}

# @node_port_check
# Check if ENVIRONMENT VARIABLE NODE_PORT is LISTENING or.
function node_port_check() {
    local NODE_PORT_STATUS=0
    for ip in ${IP_LIST[@]}; do
        if [ -n "${NODE_PORT}" ]; then
            $SSH root@${ip} ss -ntl | grep ":${NODE_PORT}[[:space:]]" &>/dev/null && NODE_PORT_STATUS=1
        else
            NODE_PORT=80
            $SSH root@${ip} ss -ntl | grep ":${NODE_PORT}[[:space:]]" &>/dev/null && NODE_PORT_STATUS=1
        fi
        if [ "${NODE_PORT_STATUS}" == 1 ]; then
            log_error "${NODE_PORT} port has been use on ${ip}"
            exit 1
        fi
    done
}

# @hostname_check
# Check hostname is standard or.
# 1. Host name can not contain space
# 2. Host name can not start with digital
# 3. Host name can not contain punctuation except '.','-'
# example:
# bad: 1edoc2-app、edoc2app 01、edoc2@app01
# good: edoc2-app、edoc2app.01、edoc2-app01
function hostname_check() {
    local INVALID_CHAR_POSIX_STYLE=('[[:space:]]' '[[:digit:]]' '[[:punct:]]')
    for ip in ${IP_LIST[@]}; do
        hostname=$($SSH root@${ip} hostname)
        if ! echo "${hostname}" | grep -P "^\b(?:[A-Za-z][0-9A-Za-z-]{0,62})(?:\.(?:[0-9A-Za-z][0-9A-Za-z-]{0,62}))*(\.?|\b)$" &>/dev/null; then
            log_error "1. Host name can not contain space 2. Host name can not start with digital 3. Host name can not contain punctuation except '.','-'"
        fi
    done
}

function system_version_check() {
    if [ -f /etc/redhat-release ]; then
        # ARCH=$(uname -m)
        # KERNEL_MAIN_VERSION=$(uname -r | awk -F '.' '{print $1}')
        RELEASE=$(awk '{print $1}' /etc/redhat-release)
        SYSTEM_MAIN_VERSION=$(awk -F "[ |.]" '{print $4}' /etc/redhat-release)
        SYSTEM_RELEASE_VERSION=$(awk -F "[ |.]" '{print $5}' /etc/redhat-release)
        awk -F "[ |.]" '{if(($1=="CentOS" && $4==7 && $5>=4) || ($1=="Rocky" && $4==8 && $5>=6)) exit 10;else exit 11}' /etc/redhat-release
        if [ $? -eq 10 ]; then
            log_info "操作系统为 ${RELEASE} ${SYSTEM_MAIN_VERSION}.${SYSTEM_RELEASE_VERSION}，满足安装要求。"
        else
            log_error "系统版本要求RedHat系列发行版，CentOS 7.4及以上或Rocky8.6以上版本"
            exit
        fi
    else
        log_error "操作系统不是Redhat系列，请使用Redhat系列操作系统。"
        exit
    fi
}

# @logserver_resolver
# Backup current /etc/hosts -> /tmp/hosts.$(date +%Y%m%d%H%M%S).bak
# Config ip -> logserver hostname resolve.
function logserver_resolver() {
    for ip in ${IP_LIST[@]}; do
        $SSH root@${ip} "rm -f /tmp/hosts.*.bak"
        $SSH root@${ip} "cp -p /etc/hosts /tmp/hosts.$(date +%Y%m%d%H%M%S).bak"
        $SSH root@${ip} "sed -i /logserver/d /etc/hosts"
        $SSH root@${ip} "echo -e "$ip logserver" >> /etc/hosts"
    done
}

function data_path_check() {
    # ecm data path check
    data_path_create
    # middleware data path check
    if [ $REGION == "mainregion" ]; then
        middleware_dir_create
    fi
}

function path_mount_point_compare() {
    if [ "$(df -h $1 | awk 'NR!=1{print $NF}')" == "$(df -h $2 | awk 'NR!=1{print $NF}')" ]; then
        log_error "当前数据库路径和备份路径在同一个分区内,请将二者路径修改为在不同的分区"
        if [ ${RUNENV}x == "prod"x ]; then
            exit
        else
            log_warning "当前运行环境配置: test, 数据库路径和备份路径监测在同一分区，测试环境数据请做好保护。"
            sleep 3
        fi
    fi
}

function storage_check() {
    case ${STORAGE_MODE} in
    local | nas)
        for _ip in ${INDRIVE_NODE[@]}; do
            mount_record=$($SSH root@${_ip} "cat /proc/mounts | grep '" ${DATA_PATH} "'")
            if [ -z ${mount_record} ]; then
                if [ ${#INDRIVE_NODE[@]} -eq 1 ]; then
                    log_info "[$_ip]: current storage provided by local device."
                    break
                else
                    log_info "[$_ip]: please mount share storage on ${DATA_PATH}"
                    exit 1
                fi
            fi
            if [ $(echo ${mount_record} | awk '{print($3 ~ /nfs|cifs/)?0:1}') -eq 0 ]; then
                log_info "[${_ip}]: current storage is share storage.now check /etc/fstab to add auto mount."
                if $SSH root@${_ip} "cat /etc/fstab | grep -Ev '^#|^$' | grep '" ${DATA_PATH} "' &> /dev/null"; then
                    log_info "[$_ip]: /etc/fstab auto mount check done."
                else
                    log_error "[$_ip]: Please edit /etc/fstab to add auto mount record."
                    exit 1
                fi

                log_info "[${_ip}]: current storage is share storage.now check mount args."
                if [ $(echo ${mount_record} | awk '{print($4 ~ /noac/)?0:1}') -eq 0 ]; then
                    log_info "[$_ip]: mount args check done."
                else
                    log_error "[$_ip]: mount args check done, noac ags not configed. Please config it and remount."
                    exit 1
                fi
            fi
        done
        ;;
    s3 | ceph)
        l=($(echo ${S3URL} | tr ',' ' '))
        mc config host add ecm ${l[0]} ${S3ACCESS} ${S3SECRET} --api s3v4
        dd if=/dev/zero of=/tmp/10m bs=1024k count=10 &>/dev/null
        if ! mc cp /tmp/10m ecm/${S3BUCKET}/ &>/dev/null; then
            log_error "s3或ceph存储不可用,请检查存储配置"
            exit 1
        else
            mc rm ecm/${S3BUCKET}/10m &>/dev/null
        fi
        ;;
    esac
}

prepare
