#!/usr/bin/env bash

#===========================================#
# Author     : Alawn                        #
# LastUpdated: 2020-04-08                   #
# Dependency : bash, expect                 #
# Discription: Management Menu for NCBA MSL #
#===========================================#

### Variables
cur_dir=$( pwd )
base_usr=`whoami`
base_home=`cat /etc/passwd | grep $(whoami) | cut -d ':' -f 6`
usr_sh=`cat /etc/passwd | grep $(whoami) | cut -d ':' -f 7`
war_dir=${base_home}/apps/
app_list=(`ls $war_dir | grep -E "*.war" |sed 's/\.war$//g'| sed 's/\-1\.0\-SNAPSHOT//g'`)
echo -e ${app_list[0]}
echo -e ${app_list[1]}
echo -e ${app_list[2]}
echo -e ${app_list[3]}
echo -e ${app_list[4]}
echo -e ${app_list[5]}
echo -e ${app_list[6]}
echo -e ${app_list[7]}
#exit
cur_app=""
app_num=${#app_list[@]}
myip=`hostname -I | sed 's/ //g'`
domain=`hostname|sed 's/ //g'`

### User define
conf_common_dataid="common.properties"
conf_group="DEFAULT_GROUP"
conf_directory="/home/ncbamsl/conf/"
conf_center_host="10.0.0.13:9084"
profile_common="common.properties"
startup_script="${base_home}/bin/startApp-configclient.sh"
inject_script=${base_home}/.inject.script
initrc=${base_home}/.injectrc

### Constants
red='\033[0;31m'
green='\033[0;32m'
yellow='\033[0;33m'
blue='\033[36m'
gray='\033[37m'
plain='\033[0m'

declare -A module_map=()

module_map["gateway-openapi"]="ogw"
module_map["manage-openapi"]="oam"
module_map["gateway-external"]="egw"
module_map["gateway-internal"]="igw"
module_map["industry-application"]="ias"
module_map["customer"]="urm"
module_map["customer-campaign"]="ccs"
module_map["savings"]="sas"
module_map["savings-service"]="sas"
module_map["loan-service"]="lns"
module_map["loan-account"]="lon"
module_map["wallet-service"]="wls"
module_map["account"]="acm"
module_map["accounting"]="act"
module_map["basic-service"]="bap"
module_map["product"]="prd"
module_map["boss"]="bui"
module_map["batch"]="bat"
module_map["data-feed"]="dfs"
module_map["ecp-message"]="ems"
module_map["ecp-message-app"]="msc"
module_map["notification-center"]="ntc"
module_map["ecp-ops"]="ops"


### Function
main_menu()
{
    while true
    do
        clear
        echo -e
        echo -e "${blue}NCBA MSL Management Menu (RWA)${plain}"
        echo -e "--------------------------------------------------"
        echo -e "Please Enter Your Choice"
        echo -e ""
        echo -e "[${yellow}1-$app_num${plain}]:Chose Application    ${yellow}q${plain}:Quit     ${yellow}v${plain}:Version"
        echo -e "--------------------------------------------------"
        echo -e ""

        ## render app menu
        for ((i=1;i<=${#app_list[@]};i++ )); do
            hint="${app_list[$i-1]}"
            state=`get_app_state ${hint}`
            printf "${yellow}%-3s${plain} %-30s      [$([ "$state" == "running" ] && echo ${green} || echo ${red})%-7s${plain}]\n" ${i}")" ${hint} ${state} 
        done

        ## Ask user which choice and press key
        echo -e ""  && read -p "Please enter a number:" selected
        case "${selected}" in 
            [1-9]*)
                if [ "${selected}" -gt $app_num ]; then
                    #title="[${red}Error${plain}] Please only enter a number [1-$app_num]"
                    continue
                fi
                echo -e
                echo "You choose = ${app_list[${selected}-1]}"
                cur_app=${app_list[${selected}-1]}
                echo -e
                function_menu
                ;;
            q|Q)
                exit 0
                ;;
            v|V)
                ## Show all version of application
                clear
                printf "%-25s %-15s %-5s %-10s\n" "Application" "Version" "Size" "LastUpdated"
                echo -e  "-------------------------------------------------------------------"
                for ((j=1;j<=${#app_list[@]};j++ )); do
                    hint=${app_list[$j-1]}
                    pid=$(get_app_pid ${hint})
                    state=$(get_app_state ${hint})
                    version=$(get_app_version ${hint})
                    last_updated=$(get_app_last_updated ${hint})
                    size=$(get_app_size ${hint})

                    printf "${blue}%-25s${plan} ${red}%-15s${plan} ${gray}%-5s${plan} ${gray}%-10s${plan} \n" $hint $version $size $last_updated
                done
                echo -e && read -s -n1 -p "Press any key go back"
                ;;
            *)
                ## Do nothing when other key pressed 
                ;;
        esac
    done
}

initrc()
{
    if [ ! -f ${initrc} ]; then
        cat > ${initrc} <<EOF
red='\033[0;31m'
green='\033[0;32m'
yellow='\033[0;33m'
blue='\033[36m'
gray='\033[37m'
plain='\033[0m'

set -o vi
export PS1="[\`hostname\`] [\${blue}\\\$LOGNAME\${plain}]:\\\$PWD>"
alias ls="ls --color=auto"
alias grep="grep --color=auto"
export day=\`date +%d\`
alias cdl="cd \${HOME}/log/"
alias cdt="cd \${HOME}/trc/\${day}"

clear

#echo -e "\${blue} _   _    ____   ____       _        __  __   ____    _     \${plain}"
#echo -e "\${blue}| \ | |  / ___| | __ )     / \      |  \/  | / ___|  | |    \${plain}"
#echo -e "\${blue}|  \| | | |     |  _ \    / _ \     | |\/| | \___ \  | |    \${plain}"
#echo -e "\${blue}| |\  | | |___  | |_) |  / ___ \    | |  | |  ___) | | |___ \${plain}"
#echo -e "\${blue}|_| \_|  \____| |____/  /_/   \_\   |_|  |_| |____/  |_____|\${plain}"

echo -e "\${blue}__        __         _                                       _____             __  __   ____    _      \${plain}"
echo -e "\${blue}\ \      / /   ___  | |   ___    ___    _ __ ___     ___    |_   _|   ___     |  \/  | / ___|  | |     \${plain}"
echo -e "\${blue} \ \ /\ / /   / _ \ | |  / __|  / _ \  | '_  \\\` _ \  / _ \     | |    / _ \    | |\/| | \___ \  | |     \${plain}"
echo -e "\${blue}  \ V  V /   |  __/ | | | (__  | (_) | | | | | | | |  __/     | |   | (_) |   | |  | |  ___) | | |___  \${plain}"
echo -e "\${blue}   \_/\_/     \___| |_|  \___|  \___/  |_| |_| |_|  \___|     |_|    \___/    |_|  |_| |____/  |_____| \${plain}"
echo -e
echo -e "   \${yellow}You can use commands among with cdt、cdl\${plain}"
echo -e
cd
EOF

    fi

    return 0
}


inject()
{ 
    cmd=$*

    ## Define environment variable and it can be inherited into sub shell
    export HOME=${base_home}/${cur_app}
    export HWORKDIR=$HOME
    export LOGNAME=$cur_app

    ## Create RC file if it not exists
    initrc

    ## Create expect script temporary 
    script=`mktemp`

    cat <<EOF > ${script} 
spawn /usr/bin/env ${usr_sh} --norc
send ". ${initrc}\n"
EOF

    if [ $# -ge 1 ]; then
        cat <<EOF >> ${script} 
send "source <(cat <<OOF\n${cmd};exit 0\nOOF\n)\n"
EOF
    fi

    cat <<EOF >> ${script} 
interact
EOF

    ## Execute expect script for app as interact mode 
    expect ${script}
    
    ## Recover $HOME environment after sub shell has been logout
    export HOME=${base_home}
}


function_menu()
{
    #title="        Please Enter Your Operation:[1-4]"
    while true
    do
        pid=`get_app_pid ${cur_app}`
        state=`get_app_state ${cur_app}`
        version=`get_app_version ${cur_app}`
        last_updated=`get_app_last_updated ${cur_app}`
        size=`get_app_size ${cur_app}`

        clear
        echo -e ""
        printf  "Application: ${blue}%s${plain} [$([ "$state" == "running" ] && echo ${green} || echo ${red})%s${plain}]\n" ${cur_app} $state
        echo -e "--------------------------------------------------"
        printf  "Version    : ${gray}%s${plain}\n" $version
        printf  "Size       : ${gray}%s${plain}\n" $size 
        printf  "LastUpdated: ${gray}%-19s${plain}\n" $last_updated
        echo -e "--------------------------------------------------"
        echo -e "" 
        echo -e "${yellow}1)${plain}  Simulated login"
        echo -e "${yellow}2)${plain}  Startup/Restart"
        echo -e "${yellow}3)${plain}  Shutdown"
        echo -e "${yellow}4)${plain}  Logging trace"
        echo -e ""
        echo -e "${yellow}b)${plain}  Go back"
        echo -e ""

        echo -e && read -p "Please enter a number :" selected
        [ -z "${selected}" ] && selected="status"
        case "${selected}" in 
            1)
                ## Login as application user
                echo -e "${green}1${plain}) 进入系统"
                inject 
                break
                ;;
            2)
                ## Startup application
                module_name=${module_map["${cur_app}"]}
                profile_app=""

                if [ "" != "$module_name" ]; then
                    profile_app=${module_name}.properties
                else
                    profile_app=${profile_common}
                fi


                node_id=${module_name}_${domain}
                cmd="export HOME=${base_home};${startup_script} ${cur_app} -serverAddr ${conf_center_host}  -appDataId ${profile_app}   -commonDataId ${profile_common} -group ${conf_group} -filedir ${conf_directory}${moddule_name}/ -nodeId ${node_id}"
                clear
                echo -e ""
                echo -e "${blue}>> Now prepare startup application, please wait a moment...${plain}"
                #sh ${cmd}
                inject ${cmd}

                echo -e "" &&  read -s -n1 -p "Press any key continue..."
                break
                ;;
            3)
                ## Shutdown application  
                clear
                echo -e ""
                echo -e "${blue}>> Now beginning kill the application with PID:${pid}...${plain}"
                echo -e ""

                if [ "${pid}" != "" ]; then

                    kill -9  ${pid}

                    sleep 1

                    state=get_app_state

                    [ "${state}" == "running" ] &&  echo -e "${red}Application not been kill...${plain}" || echo -e "${green}Application has been killed...${plain}" 

                else
                    echo -e "${yellow}Application is not running...${plain}"
                fi

                echo -e "" &&  read -s -n1 -p "Press any key continue..."

                break
                ;;
            4)
                ## Logging trace
                echo -e "${blue}>> Trace logging...${plain}"
                echo -e ""
                #tail -f ${base_home}/${cur_app}/log/${cur_app}.out
                cmd="tail -n 50 -f ${base_home}/${cur_app}/log/${cur_app}.out"
                inject ${cmd}
                break
                ;;
            b|q|B|Q)
                break
                ;;
            *)
                ## Do nothing when other key pressed 
                ;;
        esac
    done
}

get_app_last_updated()
{
    app=$1
    last_updated=`stat --format="%y" ${war_dir}/${app}.war | sed 's/\..*//g'| sed 's/ /_/g'`
    echo -e $last_updated
}

get_app_size()
{
    app=$1
    size=`stat --format="%s" ${war_dir}/${app}.war`
    size=`expr $size / 1024 / 1024`"M"
    echo -e $size
}

get_app_state()
{
    app=$1
    pid=`ps -ef | grep "/${app}.war" | grep -v grep|awk '{print $2}'`
    echo -e $([ ! -z "${pid}" ] && echo "running" || echo "dead")
}

get_app_pid()
{
    app=$1
    echo -e $(ps -ef | grep "/${app}.war" | grep -v grep|awk '{print $2}')
}

get_app_version()
{
    app=$1
    echo -e $(unzip -p ${war_dir}/${app}.war META-INF/MANIFEST.MF  | grep Implementation-Version:  | awk -F ':' '{print $2}' | sed 's/ //g' |sed 's/\r//g' | sed 's/\n//g')
}

main_menu
exit 0
