#!/bin/bash

SCP='scp -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o LogLevel=ERROR'
SSH='ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o LogLevel=ERROR'

OUTPUT_TXT='/tmp/output.txt'
INSTALL_LOG='/tmp/edoc2_install.log'

declare -a SUCCESS
declare -a FAILURE

_NUM_REGEX='^[0-9]+$'

_color_red=$(TERM=xterm-256color tput setaf 1)
_color_normal=$(TERM=xterm-256color tput sgr0)
_color_blue=$(TERM=xterm-256color tput setaf 4)
_color_green=$(TERM=xterm-256color tput setaf 2)
_color_yellow=$(TERM=xterm-256color tput setaf 3)

function log_warning() {
    local ts=$(date -Iseconds)
    # to log file
    echo -e "$ts [WARNING] $@" >>$INSTALL_LOG
    # to console (stderr)
    echo >&2 -e "${_color_yellow}$ts [WARNING] $@${_color_normal}"
    return 0
}

function log_info() {
    local ts=$(date -Iseconds)
    # to log file
    echo -e "$ts [INFO] $@" >>$INSTALL_LOG
    # to console (stderr)
    echo >&2 -e "$ts [INFO] $@"
    return 0
}

function log_error() {
    local ts=$(date -Iseconds)
    # to log file
    echo -e "$ts [ERROR] $@" >>$INSTALL_LOG
    # to console (stderr)
    echo >&2 -e "${_color_red}$ts [ERROR] $@${_color_normal}"
    return 0
}

function log_debug() {
    local ts=$(date -Iseconds)
    if [ $_DEBUG -eq 1 ]; then
        # to log file
        echo -e "$ts [DEBUG] $@" >>$INSTALL_LOG
        # to console (stderr)
        echo >&2 -e "$ts [DEBUG] $@"
    fi
    return 0
}

function log_success() {
    local ts=$(date -Iseconds)
    # to log file
    echo -e "$ts [SUCCESS] $@" >>$INSTALL_LOG
    # to console (stderr)
    echo >&2 -e "${_color_green}$ts [SUCCESS] $@${_color_normal}"
    return 0
}

function success() {
    if [ $# -eq 1 ]; then
        SUCCESS+=("OK\t[${1//\"/\\\"/}]")
    else
        SUCCESS+=("OK\t[${1//\"/\\\"/}][${2//\"/\\\"/}]")
    fi

    return 0
}

function failure() {
    if [ $# -eq 1 ]; then
        FAILURE+=("FAIL\t[${1//\"/\\\"/}]")
    else
        FAILURE+=("FAIL\t[${1//\"/\\\"/}][${2//\"/\\\"/}]")
    fi

    log_error "$@"
    #log_important "$@"
    return 0
}

function assert_num_equals() {
    if [ $1 -ne $2 ]; then
        failure "$3" "$1!=$2"
        return 1
    fi
    return 0
}

function assert_num_greater() {
    if [ $1 -le $2 ]; then
        failure "$3" "$1<=$2"
        return 1
    fi
    return 0
}

function assert_str_equals() {
    if [ "$1" != "$2" ]; then
        failure "$3" "$1!=$2"
        return 1
    fi
    return 0
}

function is_dir_empty() {
    if [ -z "$(ls -A $1)" ]; then
        return 0 # empty
    else
        return 1 # not empty
    fi
}

function assert_success() {
    if [ $? -ne 0 ]; then
        failure "$1"
        return 1
    else
        success "$1"
        return 0
    fi
}

function assert_failure() {
    if [ $? -eq 0 ]; then
        failure "$1"
        return 1
    else
        success "$1"
        return 0
    fi
}

function abort_if_failed() {
    local exit_code=$?

    if [ $exit_code -ne 0 ]; then
        log_error "$1. Abort!"
        exit $exit_code
    fi
    return 0
}

function logging_if_failed() {
    local exit_code=$?

    if [ $exit_code -ne 0 ]; then
        log_error "$1. Abort!"
    fi
    return 0
}

# Turns a comma separated string into array
# Usage: css_to_array "a, b, c" arr
function css_to_array() {
    local __arr=$2
    eval $__arr='( ${1//,/ } )'
    return 0
}

function array_contains() {
    eval 'local arr=("${'$1'[@]}")'
    local _elem=$2

    for _e in ${arr[@]}; do
        if [ "$_e" == "$_elem" ]; then
            return 0
        fi
    done

    return 1
}

function output_contains() {
    for p in $@; do
        grep -q -s "$p" $OUTPUT_TXT
        if [ $? -ne 0 ]; then
            failure "Output does not contain $p"
            return 1
        fi
    done

    return 0
}

function print_status() {
    for elem in "${SUCCESS[@]}"; do
        # to log file
        echo -e "$elem" >>$INSTALL_LOG
        # to console (stderr)
        echo >&2 -e "${_color_green}$elem${_color_normal}"
    done

    for elem in "${FAILURE[@]}"; do
        # to log file
        echo -e "$elem" >>$INSTALL_LOG
        # to console (stderr)
        echo >&2 -e "${_color_red}$elem${_color_normal}"
    done

    if [ ${#FAILURE[@]} -gt 0 ]; then
        echo >&2 -e "${_color_green}SUCCESS: ${#SUCCESS[@]}; ${_color_red}FAILURE: ${#FAILURE[@]}"
    else
        echo >&2 -e "${_color_green}SUCCESS: ${#SUCCESS[@]}; FAILURE: ${#FAILURE[@]}${_color_normal}"
    fi
    echo -e "SUCCESS: ${#SUCCESS[@]}; FAILURE: ${#FAILURE[@]}" >>$INSTALL_LOG

    return 0
}

function interactive_input() {
    local _inputFlag=">>>"
    read -p "${_color_green}$_inputFlag ${1}:${_color_normal} " _str
    local _ret=$2
    eval $_ret='$_str'
    return 0
}

function secret_input() {
    local _passwd=
    local _inputFlag=">>>"
    read -s -n1 -p "${_color_green}$_inputFlag ${1}:${_color_normal} " _char
    while true; do
        if [ "$_char" != "" ]; then
            printf "*"
            _passwd=$_passwd$_char
            read -s -n1 _char
        else
            printf "\n"
            break
        fi
    done
    local _ret=$2
    eval $_ret='$_passwd'
    return 0
}

function print_msg() {
    echo
    echo -n ${_color_yellow}
    printf '%.0s=' {1..100}
    echo
    cat <<EOF
$@
EOF
    printf '%.0s=' {1..100}
    echo
    echo -n ${_color_normal}
}
