#! /bin/bash
MYNAME=$(basename $0)
MYDIR=$(dirname $0)
MYDIR=$(readlink -m "$MYDIR")
MYHOSTNAME=$(hostname)
VERSION="0.0.17"
VERBOSE=""
LOGFILE=""

if [ -f "$MYDIR/utilityfunctions.sh" ]; then
    source $MYDIR/utilityfunctions.sh
else
    echo "File '$MYDIR/utilityfunctions.sh' was not found." >&2
    exit 5
fi

STATUS_TEXT=""
SHUTDOWN=""
MQTT_CONFIG_FILE="$HOME/.pip/mqtt.conf"
HOST_INFO_FILE="$PROJECT_HOST_STAT_DIR/$(hostname).hostinfo"
HOST_LOG_FILE="$PROJECT_HOST_STAT_DIR/$(hostname).hostlog"
HOST_CONTAINERS_FILE="$PROJECT_HOST_STAT_DIR/$(hostname).containers"
HOST_STATUS="IDLE"

#
# Prints the help text and exits.
#
function printHelpAndExit()
{
cat <<EOF
Usage:
  $MYNAME [OPTION]...

  $MYNAME - Controls test server and uploads server status file. 

 -h, --help         Print this help and exit.
 -v, --version      Print version information and exit.
 --verbose          Print more messages.
 --log-file=FILE    Store all the messages in the given file too.

 --status=TEXT      Set a human readable string as status.
 --clear-log        Clear the host log file.
 --log=TEXT         Append a log message to the host log.
 --warning=TEXT     Append a warning message to the host log.
 --error=TEXT       Append a error message to the host log.
 --tail=FILENAME    Tail the given file and add the lines to the log file.
 --shutdown         This will actually shut down the host. Be careful!
 
 --idle             Set the status to IDLE.
 --testing          Set the status to TESTING.
 --halted           Set the status to HALTED.

EOF
    exit 0
}

ARGS=$(\
    getopt \
        -o hv \
        -l "help,verbose,version,log-file:,clear-log,log:,error:,warning:,\
tail:,status:,shutdown,\
idle,testing,halted" \
        -- "$@")

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

eval set -- "$ARGS"
while true; do
    case "$1" in
        -h|--help)
            shift
            printHelpAndExit
            ;;

        --verbose)
            shift
            VERBOSE="true"
            ;;

        -v|--version)
            shift
            printVersionAndExit
            ;;

        --log-file)
            shift
            LOGFILE=$(readlink -m "$1")
            shift
            ;;
        
        --status)
            shift
            NEW_STATUS_TEXT="$1"
            shift
            ;;

        --shutdown)
            shift
            SHUTDOWN="true"
            NEW_STATUS_TEXT="Shut down."
            ;;

        --clear-log)
            shift
            CLEAR_LOG="true"
            ;;

        --log)
            shift
            NEW_LOG_MESSAGE="$1"
            shift
            ;;
        
        --warning)
            shift
            NEW_WARNING_MESSAGE="$1"
            shift
            ;;
       
        --tail)
            shift
            TAIL_FILE="$1"
            shift
            ;;

        --error)
            shift
            NEW_ERROR_MESSAGE="$1"
            shift
            ;;

        --idle)
            shift
            NEW_HOST_STATUS="IDLE"
            ;;

        --testing)
            shift
            NEW_HOST_STATUS="TESTING"
            ;;

        --halted)
            shift
            NEW_HOST_STATUS="HALTED"
            ;;

        --)
            shift
            break
            ;;

        *)
            ;;
    esac
done

#
# Appends a new log message to the local host log file that will be uploaded tzo
# the web server.
#
function append_log_message()
{
    local log_message="$*"
    local date_string="$(date "+%Y-%m-%d %H:%M:%S")"

    echo "$date_string INFO    $log_message" >>"$HOST_LOG_FILE"
    #echo "$date_string WARNING $log_message" >>"$HOST_LOG_FILE"
    #echo "$date_string ERROR   $log_message" >>"$HOST_LOG_FILE"
}

#
# Appends a new log message to the local host log file that will be uploaded tzo
# the web server.
#
function append_warning_message()
{
    local log_message="$*"
    local date_string="$(date "+%Y-%m-%d %H:%M:%S")"

    echo "$date_string WARNING $log_message" >>"$HOST_LOG_FILE"
}

#
# Appends a new log message to the local host log file that will be uploaded tzo
# the web server.
#
function append_error_message()
{
    local log_message="$*"
    local date_string="$(date "+%Y-%m-%d %H:%M:%S")"

    echo "$date_string ERROR   $log_message" >>"$HOST_LOG_FILE"
}

#
# Prints the memory size in gigabytes.
#
function get_memory_size()
{
    local number=$(free | awk '/^Mem:/{print $2}')
    let number/=1000
    let number/=1000

    echo $number
}

function get_disk_size()
{
    local device_home
    local device_lxc

    local number=0
    local check_home

    if [ -d "/var/lib/lxc" ]; then
        let number+=$(df "/var/lib/lxc" | tail -n1 | awk '{print $2}')
        device_lxc=$(df "/var/lib/lxc" | tail -n1 | awk '{print $1}')
    fi
        
    device_home=$(df "/home" | tail -n1 | awk '{print $1}')

    if [ -z "$number" ]; then
        check_home="true"
    elif [ "$device_lxc" != "$device_home" ]; then
        check_home="true"
    fi

    if [ -n "$check_home" ]; then
        let number+=$(df /home | tail -n1 | awk '{print $2}')
    fi

    let number/=1000
    let number/=1000

    echo $number
}

function get_load()
{
    cat /proc/loadavg | awk '{print $1}'
}

#
# Collects the information about this host and prints it into the standard
# output. 
#
function collect_host_info()
{
    cat <<EOF
HOSTNAME="$(hostname)"
NUMBER_OF_CORES=$(nproc)
MEMORY_GIGABYTES=$(get_memory_size)
DISK_GIGABYTES=$(get_disk_size)
NUMBER_OF_CONTAINERS=$(get_number_of_containers)
AVERAGE_LOAD=$(get_load)
HOST_STATUS="$HOST_STATUS"
STATUS_TEXT="$STATUS_TEXT"
EOF
}

function send_host_info()
{
    local hostname=$(hostname)
    local topic
    local message

    if [ ! -f "$HOST_INFO_FILE" ]; then
        printVerbose "No file '$HOST_INFO_FILE' found."
        return 1
    fi

    if [ ! -f "$MQTT_CONFIG_FILE" ]; then
        printVerbose "No file '$MQTT_CONFIG_FILE' found."
        return 1
    fi

    source "$MQTT_CONFIG_FILE"
    source "$HOST_INFO_FILE"

    topic="stat/${hostname}/control"
    message="{\"hostname\": \"$hostname\", \"status\": \"$HOST_STATUS\", \
\"status_text\": \"$STATUS_TEXT\"}"

    printVerbose "  server: $MQTT_SERVER"
    printVerbose "   topic: $topic"
    printVerbose " message: $message"
    mosquitto_pub \
        -u "$MQTT_USER" \
        -P "$MQTT_PASSWORD" \
        -h "$MQTT_SERVER" \
        -p "$MQTT_PORT" \
        -t "$topic" \
        -m "$message"
}

#
# Loading the properties, then refreshing the properties we got from the command
# line.
#
if [ -f "$HOST_INFO_FILE" ]; then
    source "$HOST_INFO_FILE"
fi

if [ "$NEW_STATUS_TEXT" ]; then
    STATUS_TEXT="$NEW_STATUS_TEXT"
fi

if [ "$NEW_HOST_STATUS" ]; then
    HOST_STATUS="$NEW_HOST_STATUS"
fi

#
#
#
if [ "$CLEAR_LOG" ]; then
    rm -f "$HOST_LOG_FILE"
fi

if [ ! -f "$HOST_LOG_FILE" ]; then
    append_log_message "Starting log file in '${MYHOSTNAME}:${HOST_LOG_FILE}'."
fi

if [ "$TAIL_FILE" ]; then
    append_log_message "The last lines of '$TAIL_FILE':"
    if [ -f "$TAIL_FILE" ]; then
        tail -n 100 "$TAIL_FILE" >>"$HOST_LOG_FILE"
    else
        append_error_message "File '$TAIL_FILE' was not found."
    fi
fi

if [ "$NEW_LOG_MESSAGE" ]; then
    append_log_message "$NEW_LOG_MESSAGE"
fi

if [ "$NEW_WARNING_MESSAGE" ]; then
    append_warning_message "$NEW_WARNING_MESSAGE"
fi

if [ "$NEW_ERROR_MESSAGE" ]; then
    append_error_message "$NEW_ERROR_MESSAGE"
fi

#
# Collecting some information about the host and storing in a file.
#
collect_host_info >"$HOST_INFO_FILE"
if [ "$VERBOSE" ]; then
    cat "$HOST_INFO_FILE"
fi

#Lets not use MQTT yet. We have no system config for it and we don't need it.
#send_host_info

if [ "$(which lxc-ls)" ]; then
    sudo lxc-ls -f >"$HOST_CONTAINERS_FILE"
else
    echo "" >"$HOST_CONTAINERS_FILE"
fi

if [ "$SHUTDOWN" = "true" ]; then
    if [ $(hostname) != "lpere-home" ]; then
        sudo poweroff
    fi
fi

