#!/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 sr-list name-label="Local storage" --minimal
}

function get_local_sr_path {
    echo "/var/run/sr-mount/$(get_local_sr)"
}

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
}
