#!/bin/bash

function xapi_plugin_location {
    for PLUGIN_DIR in "/etc/xapi.d/plugins/" "/usr/lib/xcp/plugins/" "/usr/lib/xapi/plugins"; do
        if [ -d $PLUGIN_DIR ]; then
            echo $PLUGIN_DIR
            return 0
        fi
    done
    return 1
}

function zip_snapshot_location {
    echo $1 | sed "s:\.git$::;s:$:/zipball/$2:g"
}

function create_directory_for_kernels {
    if [ -d "/boot/guest" ]; then
        echo "INFO: /boot/guest directory already exists, using that" >&2
    else
        local LOCALPATH="$(get_local_sr_path)/os-guest-kernels"
        mkdir -p $LOCALPATH
        ln -s $LOCALPATH /boot/guest
    fi
}

function create_directory_for_images {
    if [ -d "/images" ]; then
        echo "INFO: /images directory already exists, using that" >&2
    else
        local LOCALPATH="$(get_local_sr_path)/os-images"
        mkdir -p $LOCALPATH
        ln -s $LOCALPATH /images
    fi
}

function extract_remote_zipball {
    local ZIPBALL_URL=$1

    local LOCAL_ZIPBALL=$(mktemp)
    local EXTRACTED_FILES=$(mktemp -d)

    {
        wget -nv $ZIPBALL_URL -O $LOCAL_ZIPBALL --no-check-certificate
        unzip -q -o $LOCAL_ZIPBALL -d $EXTRACTED_FILES
        rm -f $LOCAL_ZIPBALL
    } >&2

    echo "$EXTRACTED_FILES"
}

function find_xapi_plugins_dir {
    find $1 -path '*/xapi.d/plugins' -type d -print
}

function install_xapi_plugins_from {
    local XAPI_PLUGIN_DIR
    local EXTRACTED_FILES
    local EXTRACTED_PLUGINS_DIR

    EXTRACTED_FILES="$1"

    XAPI_PLUGIN_DIR=$(xapi_plugin_location)

    EXTRACTED_PLUGINS_DIR=$(find_xapi_plugins_dir $EXTRACTED_FILES)

    cp -pr $EXTRACTED_PLUGINS_DIR/* $XAPI_PLUGIN_DIR
    chmod a+x ${XAPI_PLUGIN_DIR}*
}

function get_local_sr {
    xe pool-list params=default-SR minimal=true
}

function get_local_sr_path {
    pbd_path="/var/run/sr-mount/$(get_local_sr)"
    pbd_device_config_path=`xe pbd-list sr-uuid=$(get_local_sr) params=device-config | grep " path: "`
    if [ -n "$pbd_device_config_path" ]; then
        pbd_uuid=`xe pbd-list sr-uuid=$(get_local_sr) minimal=true`
        pbd_path=`xe pbd-param-get uuid=$pbd_uuid param-name=device-config param-key=path || echo ""`
    fi
    echo $pbd_path
}

function find_ip_by_name() {
    local guest_name="$1"
    local interface="$2"

    local period=10
    local max_tries=10
    local i=0

    while true; do
        if [ $i -ge $max_tries ]; then
            echo "Timeout: ip address for interface $interface of $guest_name"
            exit 11
        fi

        ipaddress=$(xe vm-list --minimal \
                    name-label=$guest_name \
                    params=networks | sed -ne "s,^.*${interface}/ip: \([0-9.]*\).*\$,\1,p")

        if [ -z "$ipaddress" ]; then
            sleep $period
            ((i++))
        else
            echo $ipaddress
            break
        fi
    done
}

function _vm_uuid() {
    local vm_name_label

    vm_name_label="$1"

    xe vm-list name-label="$vm_name_label" --minimal
}

function _create_new_network() {
    local name_label
    name_label=$1

    xe network-create name-label="$name_label"
}

function _multiple_networks_with_name() {
    local name_label
    name_label=$1

    # A comma indicates multiple matches
    xe network-list name-label="$name_label" --minimal | grep -q ","
}

function _network_exists() {
    local name_label
    name_label=$1

    ! [ -z "$(xe network-list name-label="$name_label" --minimal)" ]
}

function _bridge_exists() {
    local bridge
    bridge=$1

    ! [ -z "$(xe network-list bridge="$bridge" --minimal)" ]
}

function _network_uuid() {
    local bridge_or_net_name
    bridge_or_net_name=$1

    if _bridge_exists "$bridge_or_net_name"; then
        xe network-list bridge="$bridge_or_net_name" --minimal
    else
        xe network-list name-label="$bridge_or_net_name" --minimal
    fi
}

function add_interface() {
    local vm_name_label
    local bridge_or_network_name

    vm_name_label="$1"
    bridge_or_network_name="$2"
    device_number="$3"

    local vm
    local net

    vm=$(_vm_uuid "$vm_name_label")
    net=$(_network_uuid "$bridge_or_network_name")
    xe vif-create network-uuid=$net vm-uuid=$vm device=$device_number
}

function setup_network() {
    local bridge_or_net_name
    bridge_or_net_name=$1

    if ! _bridge_exists "$bridge_or_net_name"; then
        if _network_exists "$bridge_or_net_name"; then
            if _multiple_networks_with_name "$bridge_or_net_name"; then
                cat >&2 << EOF
ERROR: Multiple networks found matching name-label to "$bridge_or_net_name"
please review your XenServer network configuration / localrc file.
EOF
                exit 1
            fi
        else
            _create_new_network "$bridge_or_net_name"
        fi
    fi
}

function bridge_for() {
    local bridge_or_net_name
    bridge_or_net_name=$1

    if _bridge_exists "$bridge_or_net_name"; then
        echo "$bridge_or_net_name"
    else
        xe network-list name-label="$bridge_or_net_name" params=bridge --minimal
    fi
}

function xenapi_ip_on() {
    local bridge_or_net_name
    bridge_or_net_name=$1

    ifconfig $(bridge_for "$bridge_or_net_name") | grep "inet addr" | cut -d ":" -f2 | sed "s/ .*//"
}

function xenapi_is_listening_on() {
    local bridge_or_net_name
    bridge_or_net_name=$1

    ! [ -z $(xenapi_ip_on "$bridge_or_net_name") ]
}

function parameter_is_specified() {
    local parameter_name
    parameter_name=$1

    compgen -v | grep "$parameter_name"
}

function append_kernel_cmdline()
{
    local vm_name_label
    local kernel_args

    vm_name_label="$1"
    kernel_args="$2"

    local vm
    local pv_args

    vm=$(_vm_uuid "$vm_name_label")
    pv_args=$(xe vm-param-get param-name=PV-args uuid=$vm)
    xe vm-param-set PV-args="$pv_args $kernel_args" uuid=$vm
}

function destroy_all_vifs_of()
{
    local vm_name_label

    vm_name_label="$1"

    local vm

    vm=$(_vm_uuid "$vm_name_label")
    IFS=,
    for vif in $(xe vif-list vm-uuid=$vm --minimal); do
        xe vif-destroy uuid="$vif"
    done
    unset IFS
}

function have_multiple_hosts() {
    xe host-list --minimal | grep -q ","
}

function attach_network() {
    local bridge_or_net_name

    bridge_or_net_name="$1"

    local net
    local host

    net=$(_network_uuid "$bridge_or_net_name")
    host=$(xe host-list --minimal)

    xe network-attach uuid=$net host-uuid=$host
}

function set_vm_memory() {
    local vm_name_label
    local memory

    vm_name_label="$1"
    memory="$2"

    local vm

    vm=$(_vm_uuid "$vm_name_label")

    xe vm-memory-limits-set \
        static-min=${memory}MiB \
        static-max=${memory}MiB \
        dynamic-min=${memory}MiB \
        dynamic-max=${memory}MiB \
        uuid=$vm
}

function max_vcpus() {
    local vm_name_label

    vm_name_label="$1"

    local vm
    local host
    local cpu_count

    host=$(xe host-list --minimal)
    vm=$(_vm_uuid "$vm_name_label")

    cpu_count=$(xe host-param-get \
        param-name=cpu_info \
        uuid=$host |
        sed -e 's/^.*cpu_count: \([0-9]*\);.*$/\1/g')

    if [ -z "$cpu_count" ]; then
        # get dom0's vcpu count
        cpu_count=$(cat /proc/cpuinfo | grep processor | wc -l)
    fi

    # Assert cpu_count is not empty
    [ -n "$cpu_count" ]

    # Assert ithas a numeric nonzero value
    expr "$cpu_count" + 0

    xe vm-param-set uuid=$vm VCPUs-max=$cpu_count
    xe vm-param-set uuid=$vm VCPUs-at-startup=$cpu_count
}
