# -*-Shell-script-*-
#
# functions     This file contains functions used panini script
#
#
# Panini function check
#
# Copyright (c) 2015-2017 by Cisco Systems, Inc.
# All rights reserved.
#

# source PD-function library
. /etc/init.d/spirit_pd.sh

# source Libvirt Conf File
. /etc/libvirt/libvirtd.conf

# source logging library
. /etc/init.d/spirit_log.sh

get_board_type

if [[ $PD_BOARD_INST_CONF = "" ]]; then
    readonly PD_BOARD_INST_CONF="/etc/init.d/PD_board_install.cfg"
fi

if [[ $PD_BOOTSTRAP = "" ]]; then
    readonly PD_BOOTSTRAP="/etc/init.d/calvados_bootstrap.cfg"
fi

if [[ $INSTALL_PARAMS_OVERRIDE = "" ]]; then
    readonly INSTALL_PARAMS_OVERRIDE="/etc/init.d/install_params.sh"
fi

SYSADMIN_PATH_FILE="/var/run/sysadmin_path"
XR_PATH_FILE="/var/run/xr_path"
STANDARD_LIBVIRT_PORT=16509
DOCKER_PORT=2376

# Do not launch vm from installer image
# Do not launch vm if image is running from ramdisk
function calvados_launch_check {
  get_board_type
  # Skip launch check for Fretta membooted cards
  if [ "${PLATFORM}" == "fretta" ]; then
    if [ "${BOARDTYPE}" == "XC" -o "${BOARDTYPE}" == "FC" ]; then
      return 0
    fi
  fi
  # Skip start of vm for install iso
  CMDCHEK=`cat /proc/cmdline | grep install=`
  if [ -z "$CMDCHEK" ]; then
    # Do not start VM if we are running from /dev/ram
    RAMCHK=`cat /proc/cmdline | grep "/dev/ram"`
    if [ -z "$RAMCHK" ]; then
      # Ok to start vm only if we running from disk
      ROOTDEV=`cat /proc/cmdline | grep root=`
      if [ -n "$ROOTDEV" ]; then
        return 0
      fi
    fi
  fi
  return 1
}

function launch_check {
  calvados_launch_check 
}

#
# Print a shell backtrace. Useful to see how your script function was sourced
# and called.
#
function backtrace () {
    local deptn=${#FUNCNAME[@]}

    for ((i=1; i<$deptn; i++)); do
        local func="${FUNCNAME[$i]}"
        local line="${BASH_LINENO[$((i-1))]}"
        local src="${BASH_SOURCE[$((i-1))]}"
        printf '%*s at: %s(), %s, line %s\n' $i '' $func $src $line
    done
}


#
# set_rootfs_var
#
function set_rootfs_var ()
{
    if [[ $# -ne 2 ]]; then
        return;
    fi

    local key=$1
    local value=$2

    case "$key" in
    SYSADMIN_PATH)
        echo "SYSADMIN_PATH=$value" > $SYSADMIN_PATH_FILE
        ;;

    XR_PATH)
        echo "XR_PATH=$value" > $XR_PATH_FILE
        ;;

    *)
        declare -F platform_log &>/dev/null && \
            platform_log "set_rootfs_var: Unknown key $key"
        ;;
    esac

    #
    # Invoke the PD counterpart to override or add functionality, if required.
    #
    declare -F pd_set_rootfs_var &>/dev/null && \
                        pd_set_rootfs_var "$key" "$value"

}

#
# populate_rootfs_vars
#
function populate_rootfs_vars ()
{
    if [[ -f $SYSADMIN_PATH_FILE ]]; then
        . $SYSADMIN_PATH_FILE
    fi
    if [[ -f $XR_PATH_FILE ]]; then
        . $XR_PATH_FILE
    fi

    #
    # Invoke the PD counterpart to override or add functionality, if required.
    #
    declare -F pd_populate_rootfs_vars &>/dev/null && pd_populate_rootfs_vars

}


function dump_board_install_parameters_to_file 
{
    outfile=$1

    # clear out any old instances of this file
    if [ -f $outfile ]; then
       rm -f $outfile
    fi

    # We don't want this to be executable script
    # echo "#!/bin/bash" >> $outfile

    echo "MAIN_DISK="$MAIN_DISK >> $outfile
    echo "SECONDARY_DISK="$SECONDARY_DISK >> $outfile
    echo "DISK_HOST_BOOT_PART_SIZE="$DISK_HOST_BOOT_PART_SIZE >> $outfile
    echo "DISK_HOST_DATA_PART_SIZE="$DISK_HOST_DATA_PART_SIZE >> $outfile
    echo "DISK_HOST_EFI_PART_SIZE="$DISK_HOST_EFI_PART_SIZE >> $outfile
    echo "DISK_HOST_BOOT_SIZE="$DISK_HOST_BOOT_SIZE >> $outfile
    echo "DISK_HOST_CONFIG_SIZE="$DISK_HOST_CONFIG_SIZE >> $outfile
    echo "DISK_HOST_LOG_SIZE="$DISK_HOST_LOG_SIZE >> $outfile
    echo "DISK_HOST_SCRATCH_SIZE="$DISK_HOST_SCRATCH_SIZE >> $outfile

    echo "DISK_CALVADOS_BOOT_SIZE="$DISK_CALVADOS_BOOT_SIZE >> $outfile
    echo "DISK_CALVADOS_DATA_SIZE="$DISK_CALVADOS_DATA_SIZE >> $outfile
    echo "DISK_CALVADOS_REPO_SIZE="$DISK_CALVADOS_REPO_SIZE >> $outfile
    echo "DISK_CALVADOS_CONFIG_SIZE="$DISK_CALVADOS_CONFIG_SIZE >> $outfile

    echo "DISK_CALVADOS_LOG_SIZE="$DISK_CALVADOS_LOG_SIZE >> $outfile
    echo "DISK_CALVADOS_SCRATCH_SIZE="$DISK_CALVADOS_SCRATCH_SIZE >> $outfile

    echo "DISK_XR_BOOT_SIZE="$DISK_XR_BOOT_SIZE >> $outfile
    echo "DISK_XR_DATA_SIZE="$DISK_XR_DATA_SIZE >> $outfile
    echo "DISK_XR_CONFIG_SIZE="$DISK_XR_CONFIG_SIZE >> $outfile
    echo "DISK_XR_LOG_SIZE="$DISK_XR_LOG_SIZE >> $outfile
    echo "DISK_XR_SCRATCH_SIZE="$DISK_XR_SCRATCH_SIZE >> $outfile

    echo "DISK_SSD_HOST_SIZE="$DISK_SSD_HOST_SIZE >> $outfile
    echo "DISK_SSD_CALVADOS_SIZE="$DISK_SSD_CALVADOS_SIZE >> $outfile
    echo "DISK_SSD_XR_SIZE="$DISK_SSD_XR_SIZE >> $outfile

    if [[ "$NUM_EXTRA_PARTS" -gt 0 ]]; then
        echo "NUM_EXTRA_PARTS="$NUM_EXTRA_PARTS >> $outfile
        for (( i=1; i<=$NUM_EXTRA_PARTS; i++ )); do
            PART_SIZE="EXTRA_PART_SIZE${i}"
            PART_NAME="EXTRA_PART_NAME${i}"
            FS_VOL_LBL="EXTRA_PART_VOL_LBL${i}"

            echo "EXTRA_PART_SIZE${i}="${!PART_SIZE} >> $outfile
            echo "EXTRA_PART_NAME${i}="${!PART_NAME} >> $outfile
            echo "EXTRA_PART_VOL_LBL${i}="${!FS_VOL_LBL} >> $outfile
        done
   fi

}

# Convert hex base ip address to dot-decimal notation
# $1: hex ip address, eg. 0A000210
# return: dot-decimal ip address, eg. 10.0.2.16
function convert_ip() {
    local HEX_IP=$1
    # Parse hex host ip address to dot-decimal format
    local IP_P1=$((16#${HEX_IP:0:2}))
    local IP_P2=$((16#${HEX_IP:2:2}))
    local IP_P3=$((16#${HEX_IP:4:2}))
    local IP_P4=$((16#${HEX_IP:6:2}))

    local DEC_IP=${IP_P1}.${IP_P2}.${IP_P3}.${IP_P4}

    echo $DEC_IP
}

# run cmd if it is defined as bash function
# $1: cmd to be run
function check_and_run() {
    local cmd=$1

    type -t $cmd  >& /dev/null

    if [ $? -eq 0 ] ; then
        $cmd
    fi
}

function set_proc_sys_net {
    # send first TCP keepalive  after 30 sec 
    echo 30 > /proc/sys/net/ipv4/tcp_keepalive_time
    # and then every 10 sec 
    echo 10 > /proc/sys/net/ipv4/tcp_keepalive_intvl
    # send four probes.
    # This should result into 30+10*4 = 70sec before disconnect
    echo 4 > /proc/sys/net/ipv4/tcp_keepalive_probes
}
#
# Function to read TCP Port from Libvirtd.conf file 
# to see whether standard port is overridden 
#
function get_tcp_port {
if test ${tcp_port+defined}; then 
        echo $tcp_port  
else 
        echo $STANDARD_LIBVIRT_PORT  
fi

}

# Is app hosting enabled on this platform?
#
function app_host_is_enabled()
{
    get_board_type
    if [[ "$BOARDTYPE" == "RP" ]]; then
       if [[ -z "$APP_HOST_ENABLE" ]]; then
           source $PD_BOOTSTRAP
       fi
       if [[ "$APP_HOST_ENABLE" == "TRUE" ]]; then
           true
           return
       fi
    fi

    false
    return
}

#
# Is app hosting enabled on this platform?
#
function app_host_is_enabled()
{
    get_board_type
    if [[ "$BOARDTYPE" == "RP" ]]; then
       if [[ -z "$APP_HOST_ENABLE" ]]; then
           source $PD_BOOTSTRAP
       fi
       if [[ "$APP_HOST_ENABLE" == "TRUE" ]]; then
           true
           return
       fi
    fi

    false
    return
}

# Function to decide whether to enable Port-forwarding on LXC based Platforms
# Currently equivalent to 'is app hosting enabled?'
# This could be overridden by PD Function
function do_port_forward {
    declare -F app_host_is_enabled &>/dev/null && app_host_is_enabled
}

#
# Add a field to the cmdline starting with __ only if it is not present already
#
function cmdline_add_uniq()
{
    local cmdline=$1
    local toadd=$2
    local target=$3

    echo $cmdline | grep -q "\<$toadd\>" -
    if [ $? -ne 0 ]; then
        sed -i "s;\(platform=\);$toadd \1;g" $target
    fi
}

#
# Give a chance to debug on error conditions
#
function drop_to_console_for_debug()
{
    local debug=
    read -t 5 -p "Enter 'y' within 5 seconds to drop to bash for debug: " debug
    if [[ "$debug" = "y" ]]; then
        echo "Entering bash shell:"
        /bin/bash
    else
        echo "Continuing"
    fi
}

#
# Run a critical command and complain if it fails, dropping to bash for
# debugging
#
function run_and_check()
{
    local cmd="$*"
    local last_cmd_log=/tmp/log.cmd.$$
    local PREFIX="`date -u`: -- "

    declare -F platform_log &>/dev/null && platform_log "RUN: $cmd"

    ($cmd 2>&1) | sed "s/^/${PREFIX}/g" >$last_cmd_log

    local RET=${PIPESTATUS[0]}
    if [[ $RET -ne 0 ]]; then
        step_log_console "ERROR: \"$cmd\" failed:"

        cat $last_cmd_log

        drop_to_console_for_debug
    fi

    cat $last_cmd_log >> /tmp/log
    /bin/rm -f $last_cmd_log

    return $RET
}
