# Copyright (c) 2012 NTT DOCOMO, INC.
# Copyright 2012 Hewlett-Packard Development Company, L.P.
#
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
#    not use this file except in compliance with the License. You may obtain
#    a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#    License for the specific language governing permissions and limitations
#    under the License.

source /iscsi-func

function configure_vmedia_dir() {
    VMEDIA_MOUNT_POINT="/vfloppy_mnt"
    VMEDIA_DIR="/vfloppy"
    VMEDIA_CONFIG_FILE="parameters.txt"
    VMEDIA_DEVICE_BY_LABEL="/dev/disk/by-label/ir-vfd-dev"

    # Wait for some seconds for kernel to finish initializing the
    # virtual media devices.
    wait_for 5 1 "ls $VMEDIA_DEVICE_BY_LABEL"
    if [[ $? != 0 ]]; then

        # TODO(rameshg87) - 04/29/15 : This block of code is there only
        # for backward compatibility to older versions of Ironic. Remove this
        # after 2 releases. Ironic will now assign labels to Virtual Media
        # devices.
        SYSFS_DEVICE_MODELS="/sys/class/block/*/device/model"
        SYSFS_VMEDIA_DEVICE_MODEL="virtual media"

        grep -q -i "$SYSFS_VMEDIA_DEVICE_MODEL" $SYSFS_DEVICE_MODELS
        if [[ $? != 0 ]]; then
            echo "Error finding the virtual floppy device on the node."
            troubleshoot
        fi

        # Find the virtual media device from the kernel sysfs file system.
        VMEDIA_DEVICE=$(grep -l -i "$SYSFS_VMEDIA_DEVICE_MODEL" $SYSFS_DEVICE_MODELS | awk -F'/' '{print $5}')
        if [[ -z $VMEDIA_DEVICE ]]; then
            echo "Error finding the virtual floppy device on the node."
            troubleshoot
        fi
        VMEDIA_DEVICE_FILE="/dev/$VMEDIA_DEVICE"
    else
        VMEDIA_DEVICE_FILE="$VMEDIA_DEVICE_BY_LABEL"
    fi

    # Mount the virtual media device
    mkdir -p $VMEDIA_MOUNT_POINT
    mount $VMEDIA_DEVICE_FILE $VMEDIA_MOUNT_POINT
    if [[ $? != 0 ]]; then
        echo "Error mounting virtual media device $VMEDIA_DEVICE_FILE"
        troubleshoot
    fi

    # Copy the contents of the virtual media to a directory in root
    # filesystem so that we can unmount virtual media soon.
    cp -rf $VMEDIA_MOUNT_POINT $VMEDIA_DIR
    umount $VMEDIA_MOUNT_POINT
}

function get_kernel_parameter() {
    if [ "$BOOT_METHOD" = "$VMEDIA_BOOT_TAG" ]; then
        echo $(find_parameter_from_file $1 "$VMEDIA_DIR/$VMEDIA_CONFIG_FILE")
    else
        echo $(find_parameter_from_file $1 "/proc/cmdline")
    fi
}

function find_parameter_from_file() {

    local paramname=$1
    local filename=$2

    for i in `cat $filename`; do
        case "$i" in
            ${paramname}=*)
                echo "${i#${paramname}=}"
                return 0
            ;;
            ${paramname})
                echo ""
                return 0
            ;;
            *)
            ;;
        esac
    done

    echo ""
    return 1
}

function string_contains() {
  local string=$1
  local word=$2
  if [ "$string" != "${string/$word/}" ]; then
    return 0
  else
    return 1
  fi
}

function load_modules_by_udev() {
    udevadm trigger --action=add
    udevadm settle
}

function strip_dev() {
    echo "$1" | sed -e 's:^/dev/::'
}

function prepend_dev() {
    case "$1" in
    /dev/*)
        echo "$1"
        ;;
    *)
        echo "/dev/$1"
        ;;
    esac
}

function whole_disk_name() {
    local dev=`prepend_dev "$1"`
    case "$dev" in
    /dev/sd*|/dev/hd*|/dev/vd*|/dev/xvd*)
        echo "$dev" | sed -e 's/[0-9]*$//'
        ;;
    /dev/cciss/*)
        echo "$dev" | sed -e 's/p[0-9]*$//'
        ;;
    *)
        echo ""
        return 1
        ;;
    esac
}

function partition_name() {
    local dev=`prepend_dev "$1"`
    local part=$2
    case "$dev" in
    /dev/sd*|/dev/hd*|/dev/vd*|/dev/xvd*)
        echo "${dev}${part}"
        ;;
    /dev/cciss/*)
        echo "${dev}p${part}"
        ;;
    *)
        echo ""
        return 1
        ;;
    esac
}

function find_interface() {
    local mac=$1
    local interface
    interface=$(ip link show | grep -B1 -i $mac | awk '/mtu/ { print $2 }')
    if [ -n "$interface" ]; then
        echo "${interface%:}"
        return 0
    else
        # Note(moshele): try to find the InfinBand interface by
        # matching the InfinBand MAC upper and lower
        # 3 octets to the GUID lower and upper 3 octets.
        local upper_octs=${mac:0:8}
        local lower_octs=${mac:9:16}
        ib_re="${upper_octs}:[A-F0-9][A-F0-9]:[A-F0-9][A-F0-9]:${lower_octs}"
        interface=$(ip link show | grep -B1 -i ${ib_re} | grep mtu | \
                   awk {'print $2'})
        if [ -n "$interface" ]; then
            echo "${interface%:}"
            return 0
        fi
        return 1
    fi
}

function set_mac() {
    local dev=$1
    local mac=$2
    ip link set "$dev" address "$mac"
}

function swap_ifname() {
    local dev=$1
    local dev2=$2
    if [ "$dev" = "$dev2" ]; then
        return
    fi
    if ip link show "$dev2" >/dev/null; then
        # dev2 exists
        # swap device name
        ip link set "$dev" name "_$dev"
        ip link set "$dev2" name "$dev"
        ip link set "_$dev" name "$dev2"
    else
        ip link set "$dev" name "$dev2"
    fi
}

function partition_exists() {
    local dev=$1
    dev=`strip_dev "$dev"`
    if tail -n +3 /proc/partitions | grep "$dev" >/dev/null; then
        return 0
    else
        return 1
    fi
}

function find_disk() {
    local disks=$1
    local dev

    # find device
    local OLD_IFS=$IFS
    IFS=,
    for i in $disks; do
        dev=`whole_disk_name "$i"`
        if partition_exists "$dev"; then
            dev=`prepend_dev "$dev"`
            break
        fi
    dev=""
    done
    IFS=$OLD_IFS

    if [ -z "$dev" ]; then
        return 1
    fi
    echo "$dev"
    return 0
}

function check_tgtd_socket() {
    echo -n "waiting for tgtd socket..."
    if [ -e /var/run/tgtd.ipc_abstract_namespace.0 ]; then
        echo "found"
        return 0
    else
        echo "not found"
        return 1
    fi
}

wait_for(){
    LOOPS=$1
    SLEEPTIME=$2
    shift ; shift
    i=0
    while [ $i -lt $LOOPS ] ; do
        i=$((i + 1))
        eval "$@" && return 0 || true
        sleep $SLEEPTIME
    done
    return 1
}

function troubleshoot() {
    if [ "$TROUBLESHOOT" != 1 ]; then
        _DO_TROUBLESHOOT=""
        _t=0
        echo -n "Troubleshooting required, press t to launch shell."
        while [ $_t -lt 10 ]; do
            read -n 1 -t 1 _DO_TROUBLESHOOT
            _t=$(($_t + 1))
            if [ "$_DO_TROUBLESHOOT" == "t" ]; then
                export TROUBLESHOOT=1
                break
            fi
            echo -n "."
        done
        echo ""
    fi
    if [ "$TROUBLESHOOT" == 1 ]; then
        echo "Starting troubleshooting shell."
        bash
    fi
}

function safe_url_encode() {
    local str=$1
    local out=""

    for (( i=0; i<${#str}; i++ )); do
        c=${str:$i:1}
        case $c in
        [a-zA-Z0-9.-_] )
            out+="$c"
            ;;
        ' ' )
            out+="+"
            ;;
        *)
            #skip it
            ;;
        esac
    done
    echo "$out"

}

function err_msg() {
    message=$1
    if [ -z "$FIRST_ERR_MSG" ]; then
        FIRST_ERR_MSG=$(safe_url_encode "$message")
    fi
    echo "$message"
}

