#!/bin/bash

declare -r fi_update_work="/opt/fiupdate"
declare product_dir='/opt/fiupdate/NCE_info'
declare fi_update_log=''
declare work_curPath=''
declare root_pwd=''
declare admin_pwd=''
declare mainOms=''
declare analyzer_scale=''
declare analyzer_scene=''
declare fiweb=''
declare ODAAEplugin=''
declare odae_work='/opt/fiupgrade'

TMOUT=0
read -s -p "please input root password:" root_pwd
echo -e "\n"

read -s -p "please input admin password:" admin_pwd
echo -e "\n"

root_pwd=$(perl -e 'print quotemeta shift(@ARGV)' "${root_pwd}")
admin_pwd=$(perl -e 'print quotemeta shift(@ARGV)' "${admin_pwd}")
if [ -f ${fi_update_work}/conf/updadmin.properties ];then
    updadmin_pwd=`cat ${fi_update_work}/conf/updadmin.properties`
else
    echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`] updadmin.properties does not exist."
    return 1
fi

ODAAEpluginfile=`find ${fi_update_work}/package/ -name "ODAESwiftDeployPlugin*.zip" -type f`
ODAAEplugin=`basename ${ODAAEpluginfile}`

function get_cur_path()
{
    cd "$(dirname "${BASH_SOURCE-$0}")"
    work_curPath="${PWD}"
    fi_scriptName="$(basename "${BASH_SOURCE-$0}")"
    cd - >/dev/null
}

function logDef()
{
    local funcName="$1"; shift
    local logLevel="$1"; shift
    local lineNO="$1"; shift

    local logTime="$(date -d today +'%Y-%m-%d %H:%M:%S')"
    printf "[${logTime}] ${logLevel} $* [${g_scriptName}(${funcName}):${lineNO}]($$)\n" \
        >> "${fi_update_log}" 2>&1
}

function log_error()
{
    logDef "${FUNCNAME[1]}" "ERROR" "$@"
}

function log_info()
{
    logDef "${FUNCNAME[1]}" "INFO" "$@"
}

function init_log()
{
    if [ ! -d "$fi_update_work/log/" ]
    then
        mkdir "$fi_update_work/log/"
    fi
    fi_update_log="$fi_update_work/log/pre_update_8021.log"
    [ ! -f "${fi_update_log}" ] && touch "${fi_update_log}"
    chmod 600 "${fi_update_log}"

}

function upgrade_fi_prepare()
{

    #If upgrade fi prepare is successful, skip this step.
    upgrade_result=`cat $fi_update_work/log/pre_update_8021.log | grep "run odae precheck script success"`
    if [ "x${upgrade_result}" != "x" ]
    then
        echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`] run odae precheck script success, you do not need to do again."
        log_info "${LINENO}" "run odae precheck script success, you do not need to do again."
        if [ -d "/opt/huawei/Bigdata/upload/temp" -a "/opt/fiupgrade/ODAEDeployTool/FIPatch" ]
        then
            cp -rf /opt/fiupgrade/ODAEDeployTool/FIPatch/* /opt/huawei/Bigdata/upload/temp/ > /dev/null 2>&1
            chown -R omm:wheel /opt/huawei/Bigdata/upload/temp
        fi
        return 0
    fi
    echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`] start to run odae prepare script"
    log_info "${LINENO}" "start to run odae prepare script "
    if [ ! -d "$odae_work/ODAEDeployTool/bin/" ]
    then
        log_error "${LINENO}" "$odae_work/ODAEDeployTool/bin/ is not exists, please check"
        return 1
    fi
    cd  $odae_work/ODAEDeployTool/bin
    
    sed -i "s/ficluster_conf.json//g" $odae_work/ODAEDeployTool/etc/datamodel/FI_u2000.json

    expect <<END
    spawn bash upgrade_fi.sh prepare
    set timeout -1
    expect "*assword:"
    send "true,$root_pwd\r"
    set timeout -1
    expect "*assword:"
    send "false,$updadmin_pwd\r"
    set timeout -1
    expect "*assword:"
    send "true,$admin_pwd\r"
    set timeout -1
    expect eof

    catch wait ret
    set exit_status [lindex \$ret 3]
    exit \$exit_status
END
    
    if [ $? -ne 0 ] 
    then
        echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`] run odae precheck script failed,please check $odae_work/ODAEDeployTool/var/logs/upgrade_prepare.log"
        log_error "${LINENO}" "run odae precheck script failed,please check $odae_work/ODAEDeployTool/var/logs/upgrade_prepare.log"
        return 1
    fi
    echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`] run odae precheck script success"
    log_info "${LINENO}" "run odae precheck script success"
    
    return 0
}

function ifpreset()
{
    fi_node=$1
    expect <<END
                spawn scp -p /opt/fiupdate/pre_config.sh root@${fi_node}:/opt
                expect {
                "*yes/no*" {send "yes\r";exp_continue}
                "assword:" {send "$root_pwd\r"}
                }
                set timeout 120
                expect eof
END

    expect <<END
                spawn ssh -t root@${fi_node} "cd /opt/ ; bash pre_config.sh preset ; rm -rf /opt/pre_config.sh"
                expect {
                "*yes/no*" {send "yes\r";exp_continue}
                "assword:" {send "$root_pwd\r"}
                }
                expect {
                    "*needs to be executed again*" {exit 3}
                    "has been executed OK" {exit 0}
                }
                exit 2
END

    presetresult=$?
    return $presetresult
}

function checkpreset()
{
    product_ini=$1
    echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`] start to check preset result on fi01."
    log_info "${LINENO}" "start to check preset result on fi01."
    if [ ! -f /var/lib/sudo/Bigdata/setuptool/installSudoExecute.sh ]
    then
        echo "[`date '+%Y-%m-%d %H:%M:%S'`]The preset has been executed on FI01 wrong, try again."
        log_info "${LINENO}" "The preset has been executed on FI01 wrong, try again."
        do_preset
        if [ $? -ne 0 ]
        then
            echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`] Failed to execute the preset on FI01 again. Please check."
            log_error "${LINENO}" "Failed to execute the preset on FI01 again. Please check."
            return 1
        fi
    else
        echo "[`date '+%Y-%m-%d %H:%M:%S'`]The preset has been executed ok, do nothing."
        log_info "${LINENO}" "The preset has been executed ok, do nothing."
        return 0
    fi
    echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`] start to check preset result on fi nodes."
    log_info "${LINENO}" "start to check preset result on fi nodes."
	rm -rf iptmp.conf > /dev/null 2>&1
    cat $product_ini |grep finode= |sed 's/finode=//g' >>./iptmp.conf
    cat $product_ini |grep Analyzer_Calc_Storage | awk -F "=" {'print $2'} >>./iptmp.conf
    fi_nodes=`sort -u iptmp.conf`
    for fi_node in ${fi_nodes}
    do
        ifpreset $fi_node
        presetresult=$?
        if [ $presetresult -eq 0 ]
        then
            echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`] Checking the fi preset succeeded..."
            log_info "${LINENO}" "Checking the fi preset succeeded..."
            continue
        elif [ $presetresult -eq 3 ]
        then
            echo "[`date '+%Y-%m-%d %H:%M:%S'`]The preset has been executed on $fi_node wrong, try again."
            log_info "${LINENO}" "The preset has been executed on $fi_node wrong, try again."
            do_preset
            if [ $? -ne 0 ]
            then
                echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`] Failed to execute the preset again. Please check."
                log_error "${LINENO}" "Failed to execute the preset on FI01 again. Please check."
                return 1
            fi
            break
        fi
    done
	rm -rf iptmp.conf > /dev/null 2>&1
    rm -rf /opt/FusionInsight_UpdateService > /dev/null 2>&1
    return 0
}

function do_preset()
{
    UpdateServicefile=`find ${fi_update_work}/package/ -name "FusionInsight_UpdateService*.tar.gz" -type f`
    rm -rf /opt/FusionInsight_UpdateService > /dev/null 2>&1
    tar -xvf $UpdateServicefile -C /opt
    if [ -f /opt/FusionInsight_UpdateService/setuptool/upgrade/upgrade_setup.sh ]
    then
        expect <<END
            spawn bash /opt/FusionInsight_UpdateService/setuptool/upgrade/upgrade_setup.sh -s preset
            expect {
                "*password*:" {send "$root_pwd\r"}
            }
            set timeout 600
            expect eof
        
            catch wait ret
            set exit_status [lindex \$ret 3]
            exit \$exit_status
END

        if [ $? -ne 0 ]
        then
            echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`] Failed to execute the preset. Please check."
            log_error "${LINENO}" "Failed to execute the preset. Please check."
            return 1
        fi
    fi
    return 0
}

function update_sudoExecute()
{
    product_ini=$1
    echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`] start to update sudoExecute script."
    log_info "${LINENO}" "start to update sudoExecute script."

    rm -rf iptmp.conf > /dev/null 2>&1
    cat $product_ini |grep finode= |sed 's/finode=//g' >>./iptmp.conf
    cat $product_ini |grep Analyzer_Calc_Storage | awk -F "=" {'print $2'} >>./iptmp.conf
    fi_nodes=`sort -u iptmp.conf`
    for fi_node in ${fi_nodes}
    do
    expect <<END
                spawn scp -p /opt/fiupdate/pre_config.sh root@${fi_node}:/opt
                expect {
                "*yes/no*" {send "yes\r";exp_continue}
                "assword:" {send "$root_pwd\r"}
                }
                set timeout 120
                expect eof
END

    expect <<END
                spawn ssh -t root@${fi_node} "cd /opt/ ; bash pre_config.sh sudoexecute ; bash pre_config.sh checkagentpid ; rm -rf /opt/pre_config.sh > /dev/null 2>&1"
                expect {
                "*yes/no*" {send "yes\r";exp_continue}
                "assword:" {send "$root_pwd\r"}
                }
                set timeout 300
                expect eof
END

    done
    rm -rf iptmp.conf > /dev/null 2>&1
    return 0
}

function stop_cluster()
{
    (echo "$admin_pwd" | nohup bash $fi_update_work/stop_cluster.sh $fiweb > /tmp/stop_cluster.sh.log 2>&1 &)
    sleep 2
}

function pre_runupd()
{
    #If upgrade fi prepare is successful, skip this step.
    upgrade_result=`cat $fi_update_work/log/pre_update_cluster_8021.log | grep "update cluster stage work success"`
    if [ "x${upgrade_result}" != "x" ]
    then
        echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`] run odae preconfig script success, you do not need to do again."
        log_info "${LINENO}" "run odae preconfig script success, you do not need to do again."
        return 0
    fi
    echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`] run ODAE pre_update cluster script in ${mainOms}"
    log_info "${LINENO}" " run ODAE pre_update cluster script in ${mainOms}"
    cd /opt/fiupdate
	
    expect <<END
    spawn bash pre_update_cluster_fi_ossadm.sh
    set timeout -1
    expect "*assword:"
    send "$root_pwd\r"
    expect "*assword:"
    send "$admin_pwd\r"
    set timeout -1
    expect eof
END
    
    if [ ! -f "/opt/fiupdate/log/pre_update_cluster_8021.log" ]
    then
        echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`] pre_update cluster Run Failed "
        log_error "${LINENO}" " pre_update cluster Run Failed "
        return 1
    fi
    
    runresult=`cat /opt/fiupdate/log/pre_update_cluster_8021.log | grep 'update cluster stage work success'`
    
    if [ ! -n "$runresult" ]
    then
        echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`]  pre_update cluster Run Failed "
        log_error "${LINENO}" " pre_update cluster Run Failed "
        return 1
    fi
    
    echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`] pre_update cluster Run Success "
    log_info "${LINENO}" " pre_update cluster Run Success "
    
    return 0
}

function set_premeters()
{
    if [ ! -f "/opt/fiupdate/conf/nodes.ini" ]
    then
        echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`] FI nodes information config not exists"
        log_error "${LINENO}" "FI nodes information config not exists"
        return 1
    fi
    analyzer_scene=`cat /opt/fiupdate/conf/nodes.ini|grep feature |sed 's/feature=//g'|awk -F ';' '{print $1}'`
    analyzer_scene=`echo $analyzer_scene | tr A-Z a-z`
    analyzer_scale=`cat /opt/fiupdate/conf/nodes.ini|grep feature |sed 's/feature=//g'|awk -F ';' '{print $2}'`
    analyzer_scale=`echo $analyzer_scale | tr A-Z a-z`
    fiweb=`cat /opt/fiupdate/conf/nodes.ini|grep fiweb | sed  's/fiweb=//g'`
    mainOms=`cat /opt/fiupdate/conf/nodes.ini |grep mainOms= |sed 's/mainOms=//g'`
}

function set_timeout()
{
    if [ -f "/etc/bashrc" ]
    then
        echo "[`date '+%Y-%m-%d %H:%M:%S'`] start to check sys tmout"
        log_info "${LINENO}" "start to check sys tmout"
        tmresult=`cat /etc/bashrc|grep TMOUT`
        if [ ! -n "$tmresult" ]
        then
            echo "[`date '+%Y-%m-%d %H:%M:%S'`] sys tmout not need to change"
            log_info "${LINENO}" "sys tmout not need to change"
            return 0
        fi
        cat /etc/bashrc |grep TMOUT |while read tmout_sys
        do
            if [ ! -n "$tmout_sys" ]
            then
                echo "[`date '+%Y-%m-%d %H:%M:%S'`] sys tmout not need to change"
                log_info "${LINENO}" "sys tmout not need to change"
            else
                echo "[`date '+%Y-%m-%d %H:%M:%S'`] sys tmout need to change" 
                log_info "${LINENO}" "sys tmout need to change"
                if [[ "$tmout_sys" =~ "export" ]]
                then
                    sed -i "s/$tmout_sys/export TMOUT=0/g" /etc/bashrc
                    source /etc/bashrc
                    echo "[`date '+%Y-%m-%d %H:%M:%S'`] sys tmout change success,is to set $TMOUT" 
                    log_info "${LINENO}" "sys tmout change success,is to set $TMOUT"
                else
                    sed -i "s/$tmout_sys/TMOUT=0/g" /etc/bashrc
                    source /etc/bashrc
                    echo "[`date '+%Y-%m-%d %H:%M:%S'`] sys tmout change success,is to set $TMOUT" 
                    log_info "${LINENO}" "sys tmout change success,is to set $TMOUT"
                fi
            fi
        done
    fi
    service sshd restart
    return 0 

}

function unset_parameters()
{
    unset admin_pwd
    unset root_pwd
    unset fiweb
}


function Main()
{
    log_info "${LINENO}" "use ODAE preScript to update fi to 8.0.2.1"
    set_timeout
    if [ $? -ne 0 ]
    then
        echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`] prework set timeout failed"
        log_error "${LINENO}" "prework set timeout failed"
        return 1
    fi
    set_premeters
    if [ $? -ne 0 ]
    then
        echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`] prework set parameters failed"
        log_error "${LINENO}" "prework set paramters failed"
        return 1
    fi
    pre_runupd
    if [ $? -ne 0 ]
    then
        echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`] pre_update cluster Run Failed."
        log_error "${LINENO}" "pre_update cluster Run Failed."
        return 1
    fi

    upgrade_fi_prepare
    if [ $? -ne 0 ]
    then
        echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`] Failed to execute the prepare script before the upgrade fi"
        log_error "${LINENO}" "Failed to execute the prepare script before the upgrade fi"
        return 1
    fi
    product_all=`find $product_dir/ -name "node*.ini" -type f`
    for product in ${product_all}
    do
    {
    checkpreset ${product}
    if [ $? -ne 0 ]
    then
        echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`] Failed to execute the preset again."
        log_error "${LINENO}" "Failed to execute the preset again."
        return 1
    fi
    update_sudoExecute ${product}
    if [ $? -ne 0 ]
    then
        echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`] Failed to update sudoExecute script."
        log_error "${LINENO}" "Failed to update sudoExecute script."
        return 1
    fi
    }
    done
    stop_cluster
    sleep 8
    log_info "${LINENO}" "Preparing for the upgrade FI Succeeded " 
    return 0    
}


get_cur_path
cd "${work_curPath}"

init_log || return $?

Main
mainresult=$?
unset_parameters
exit $mainresult
