#!/bin/bash
#
# functions - OpenDaylight driver utility functions

# Get build information
function odl_update_maven_metadata_xml {
    local MAVENMETAFILE=$1
    local NEXUSPATH=$2
    local BUNDLEVERSION=$3
    local OFFLINE=$4

    if [[ "$OFFLINE" == "True" ]]; then
        return
    fi

    # Remove stale MAVENMETAFILE for cases where you switch releases
    rm -f $MAVENMETAFILE

    # Acquire the timestamp information from maven-metadata.xml
    wget -O $MAVENMETAFILE ${NEXUSPATH}/${BUNDLEVERSION}/maven-metadata.xml
}

function _odl_export_snapshot_url_pkg {
    local ODL_DIR=$1
    local ODL_URL_PREFIX=$2
    local BUNDLEVERSION=$3
    local OFFLINE=$4
    local BUNDLE_TIMESTAMP=$5

    local MAVENMETAFILE=$ODL_DIR/maven-metadata.xml
    local NEXUSPATH="${NEXUSPATH:-${ODL_URL_PREFIX}/${ODL_URL_SNAPSHOT_REPOSITORY_PATH}/org/opendaylight/integration/distribution-karaf}"

    if [ "$BUNDLE_TIMESTAMP" == "latest" ]; then
        odl_update_maven_metadata_xml $MAVENMETAFILE $NEXUSPATH $BUNDLEVERSION $OFFLINE
        if is_ubuntu; then
            install_package libxml-xpath-perl
            BUNDLE_TIMESTAMP=`xpath -e "//snapshotVersion[extension='zip'][1]/value/text()" $MAVENMETAFILE 2>/dev/null`
        else
            yum_install perl-XML-XPath
            BUNDLE_TIMESTAMP=`xpath $MAVENMETAFILE "//snapshotVersion[extension='zip'][1]/value/text()" 2>/dev/null`
        fi
    fi

    export ODL_URL=${NEXUSPATH}/${BUNDLEVERSION}
    export ODL_PKG=distribution-karaf-${BUNDLE_TIMESTAMP}.zip
}

function _odl_export_release_url_pkg {
    local ODL_URL_PREFIX=$1
    local BUNDLEVERSION=$2
    local NEXUSPATH="${NEXUSPATH:-${ODL_URL_PREFIX}/${ODL_URL_RELEASE_REPOSITORY_PATH}/org/opendaylight/integration/distribution-karaf}"

    export ODL_URL=${NEXUSPATH}/${BUNDLEVERSION}
    export ODL_PKG=distribution-karaf-${BUNDLEVERSION}.zip
}

function setup_opendaylight_package {
    if [[ -n "$ODL_SNAPSHOT_VERSION" ]]; then
        _odl_export_snapshot_url_pkg ${ODL_DIR} ${ODL_URL_PREFIX} ${ODL_BUNDLEVERSION} ${OFFLINE} ${ODL_SNAPSHOT_VERSION}
    else
        _odl_export_release_url_pkg ${ODL_URL_PREFIX} ${ODL_BUNDLEVERSION}
    fi
}

# Test if OpenDaylight is enabled
function is_opendaylight_enabled {
    [[ ,${ENABLED_SERVICES} =~ ,"odl-" ]] && return 0
    return 1
}


# Check that the bridge is up and running
function wait_for_active_bridge {
    local BRIDGE=$1
    local SLEEP_INTERVAL=$2
    local MAX_WAIT=$3

    echo "Waiting for bridge $BRIDGE to be available..."
    local testcmd="sudo ovs-vsctl list Bridge | grep $BRIDGE"
    test_with_retry "$testcmd" \
        "$BRIDGE did not become available in $MAX_WAIT seconds." \
        $MAX_WAIT $SLEEP_INTERVAL
    echo "Bridge $BRIDGE is available."
}

# Move the public IP addresses to the OVS bridge on startup,
# or back to the public interface on cleanup
function move_interface_addresses {
    local direction=$1

    if [[ -n "$ODL_PROVIDER_MAPPINGS" ]]; then
        local VETH_INTERFACE=$(echo $ODL_PROVIDER_MAPPINGS | cut -d ':' -f1)
        local PHYSICAL_INTERFACE=$(echo $ODL_PROVIDER_MAPPINGS | cut -d ':' -f2)

        if [[ "$direction" == "into_bridge" ]]; then
            _move_neutron_addresses_route "$PHYSICAL_INTERFACE" "$VETH_INTERFACE" True False "inet"
            if _has_public_ipv6_address "$PHYSICAL_INTERFACE"; then
                _move_neutron_addresses_route "$PHYSICAL_INTERFACE" "$VETH_INTERFACE" False False "inet6"
            fi
        elif [[ "$direction" == "outof_bridge" ]]; then
            _move_neutron_addresses_route "$VETH_INTERFACE" "$PHYSICAL_INTERFACE" False True "inet"
            if _has_public_ipv6_address "$VETH_INTERFACE"; then
                _move_neutron_addresses_route "$VETH_INTERFACE" "$PHYSICAL_INTERFACE" False False "inet6"
            fi
        fi
    fi
}

# Check that the interface has an IP v6 address which
# is routable on external network
function _has_public_ipv6_address {
    local interface=$1
    local interface_public_ipv6_addresses=$(ip -f inet6 a s dev "$interface" | grep -c 'global')
    echo "$interface public IPv6 address count: $interface_public_ipv6_addresses"
    if [[ "$interface_public_ipv6_addresses" != 0 ]]; then
        return 0
    else
        return 1
    fi
}
