#!/bin/bash
SYS_PATH=/etc/pkgship
OUT_PATH=/var/run/pkgship_uwsgi
if [ ! -d "$OUT_PATH" ]; then
        mkdir $OUT_PATH
fi

if [ ! -f "$SYS_PATH/package.ini" ]; then
    echo "[ERROR] $SYS_PATH/package.ini dose not exist!!!"
    exit 0
fi

user=$(id | awk '{print $2}' | cut -d = -f 2)
if [ "$user" == "0(root)" ]; then
    echo "[INFO] Current user is root"
else
    echo "[ERROR] Current user is not root, the service don't support common user."
    exit 1
fi

function check_config_file(){
    echo "[INFO] Check validation of config file."
    check_null
    
    echo "[INFO] Check validation of ip addresses."
    write_port=$(get_config "$service" "write_port")
    query_port=$(get_config "$service" "query_port")
    write_ip_addr=$(get_config "$service" "write_ip_addr")
    query_ip_addr=$(get_config "$service" "query_ip_addr")
    check_addr $write_ip_addr $write_port
    check_addr $query_ip_addr $query_port
    echo "[INFO] IP addresses are all valid."

    echo "[INFO] Check validation of numbers."
    num_vars=(backup_count max_bytes buffer-size http-timeout harakiri hour minute pool_workers)
    for var in ${num_vars[@]}
    do
        value=$(get_config "$service" $var)
        if [[ -z "$value" ]]; then
            echo "[ERROR] CAN NOT find config name $var in: $SYS_PATH/package.ini, Please check the file."
            exit 1
        fi
        check_num ${value} ${var}
    done
    echo "[INFO] All numbers are valid."

    echo "[INFO] Check validation of words."
    log_level=$(get_config "$service" "log_level")
    open=$(get_config "$service" "open")
    check_word $log_level "INFO|DEBUG|WARNING|ERROR|CRITICAL" "log_level"
    check_word $open "True|False" "open"
    echo "[INFO] All words are valid."

    echo "[INFO] Config file checked valid."

}

function check_addr(){
    ip=$1
    ret=1
    if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
        ip=(${ip//\./ })
        [[ ${ip[0]} -le 255 && ${ip[1]} -le 255 && ${ip[2]} -le 255 && ${ip[3]} -le 255 ]]
        ret=$?
    fi
    if [ $ret -ne 0 ]; then
        echo "[ERROR] Invalid ip of $1"
        exit 1
    fi
    check_num $2 "port"
    if [[ $2 -gt 65534 || $2 -lt 1025 ]]; then
        echo "[ERROR] Invalid port of $2"
        exit 1
    fi
}

function check_null(){
    list=`cat $SYS_PATH/package.ini | grep -E ^[a-z_-]+= | awk -F '=' '{if($2 == "")print $1}'`
    num=0
    for val in $list
    do
        num=$[$num+1]
    done
    if [ $num -gt 0 ]; then
        echo "[ERROR] The value of below config names is None in: $SYS_PATH/package.ini, Please check these parameters:"
        for val in $list
        do
            echo $val
        done
        exit 1
    fi
}

function check_num(){
    result=`echo $1 | grep '^[[:digit:]]*$'`
    if [ $? -ne 0 ]; then
        echo "[ERROR] $2 should be a number."
        exit 1
    fi
}

function check_word(){
    result=`echo $1 | grep -wE "$2"`
    if [ $? -ne 0 ]; then
        echo "[ERROR] $3 should be $2."
        exit 1
    fi
}


function get_config(){
    cat $SYS_PATH/package.ini | grep -E ^$2 | sed s/[[:space:]]//g | awk 'BEGIN{FS="="}{print $2}'
}

function create_config_file(){
    echo "[INFO] config type is: $service"
    daemonize=$(get_config "$service" "daemonize")
    buffer_size=$(get_config "$service" "buffer-size")
    http_timeout=$(get_config "$service" "http-timeout")
    harakiri=$(get_config "$service" "harakiri")
    uwsgi_file_path=$(find /usr/lib/ -name "packageship" | head -n 1)
    echo "[INFO] run packageship under path: $uwsgi_file_path"
    if [ $service = "manage" -o $service = "all" ];then
        write_port=$(get_config "$service" "write_port")
        write_ip_addr=$(get_config "$service" "write_ip_addr")
        if [[ -z "$daemonize" ]] || [[ -z "$buffer_size" ]] || [[ -z "$write_ip_addr" ]] || [[ -z "$http_timeout" ]] || [[ -z "$harakiri" ]] || [[ -z "$write_port" ]];
        then
            echo "[ERROR] CAN NOT find  all config name in: $SYS_PATH/package.ini, Please check the file"
            echo "[ERROR] The following config name is needed: daemonize, buffer-size, write_port, write_ip_addr, harakiri and http-timeout"
            exit 1
        fi
        if [ -z "$uwsgi_file_path" ];then
            echo "[ERROR] CAN NOT find the uwsgi file path under: /usr/lib/"
            exit 1
        fi
        echo "[INFO] manage.ini is saved to $OUT_PATH/manage.ini"
        echo "[uwsgi]
http=$write_ip_addr:$write_port
module=packageship.manage
uwsgi-file=$uwsgi_file_path/manage.py
callable=app
buffer-size=$buffer_size
pidfile=$OUT_PATH/manage.pid
http-timeout=$http_timeout
harakiri=$harakiri
enable-threads=true
daemonize=$daemonize" > $OUT_PATH/manage.ini
chmod 666 $OUT_PATH/manage.ini
    fi
    
    if [ $service = "selfpkg" -o $service = "all" ];then
        query_port=$(get_config "$service" "query_port")
        query_ip_addr=$(get_config "$service" "query_ip_addr")

        if [[ -z "$daemonize" ]] || [[ -z "$buffer_size" ]] || [[ -z "$query_ip_addr" ]] || [[ -z "$http_timeout" ]] || [[ -z "$harakiri" ]] || [[ -z "$query_port" ]];then
            echo "[ERROR] CAN NOT find  all config name in: $SYS_PATH/package.ini, Please check the file."
            echo "[ERROR] The following config name is needed: daemonize, buffer_size, query_port, query_ip_addr, harakiri and http-timeout."
            exit 1
        fi
        if [ -z "$uwsgi_file_path" ];then
            echo "[ERROR] CAN NOT find the uwsgi file path under: /usr/lib/"
            exit 1
        fi

        echo "[INFO] selfpkg.ini is saved to: $OUT_PATH/selfpkg.ini"
        echo "[uwsgi]
http=$query_ip_addr:$query_port
module=packageship.selfpkg
uwsgi-file=$uwsgi_file_path/selfpkg.py
callable=app
buffer-size=$buffer_size
pidfile=$OUT_PATH/selfpkg.pid
http-timeout=$http_timeout
harakiri=$harakiri
enable-threads=true
daemonize=$daemonize" > $OUT_PATH/selfpkg.ini
chmod 666 $OUT_PATH/selfpkg.ini
    fi

    rm -f config_file
}

function start_service(){
    if [ "`ps aux | grep "uwsgi" | grep "$1.ini"`" != "" ];then
        echo "[WARNING] $1 service is running, please STOP it first."
    else
        cd $uwsgi_file_path
        uwsgi -d --ini $OUT_PATH/$1.ini
        echo "[INFO] START uwsgi service: $1.ini"
    fi
}

function stop_service(){
    if [ ! -f "$OUT_PATH/$1.pid" ]; then
        echo "[ERROR] STOP service FAILED, $OUT_PATH/$1.pid dose not exist."
        echo "[ERROR] Please stop it manually by using [ps -aux] and [uwsgi --stop #PID]"
        exit 0
    fi

    pid=$(cat $OUT_PATH/$1.pid)
    if [ "`ps aux | awk 'BEGIN{FS=" "}{if ($2=='$pid') print $0}' | grep "$1.ini"`" != "" ];then
        uwsgi --$2 $OUT_PATH/$1.pid
        echo "[INFO] STOP uwsgi service: $1.ini"
    else
        echo "[WARNING] STOP service [FAILED], Please START the service first."
    fi
}

if [ ! -n "$1" ]
then
    echo "Usages: sh pkgshipd.sh start|stop [manage|selfpkg]"
    exit 0
fi

if [ X$2 = X ];then
    service="all"
elif [ $2 = "manage" -o $2 = "selfpkg" ];then
    service=$2
else
    echo "[ERROR] Can not phase the input of $2!!!"
    exit 0
fi

if [ $1 = "start" ]
then
    check_config_file
fi

create_config_file $service
if [ $? -ne 0 ];then  
    exit 0
fi


if [ $1 = start ]
then
    if [ $service = "all" ];then
        start_service "manage"
        start_service "selfpkg"
    else
        start_service $service
    fi
    echo "===The run log is saved into: $daemonize==="

elif [ $1 = stop ];then
    if [ $service = "all" ];then
        stop_service "manage" "stop"
        stop_service "selfpkg" "stop"
    else
        stop_service $service "stop"
    fi
    echo "===The run log is saved into: $daemonize==="

else
    echo "Usages: sh pkgshipd.sh start|stop [manage|selfpkg]"
fi
