
from __future__ import absolute_import
from __future__ import division

import os

from libvirt import libvirtError, VIR_ERR_NO_NETWORK

from vdsm.common import commands
from vdsm.common import libvirtconnection
from vdsm.network.api import DUMMY_BRIDGE
from . import expose, ExtraArgsError

EXT_IP = '/usr/sbin/ip'


def createEphemeralBridge(bridgeName):
    rc, out, err = commands.execCmd([
        EXT_IP, 'link', 'add', bridgeName, 'type', 'bridge'])
    if rc != 0:
        raise EnvironmentError(
            'Failed to create ephemeral dummy bridge. Err: %s' % err
        )


def removeEphemeralBridge(bridgeName):
    rc, out, err = commands.execCmd([
        EXT_IP, 'link', 'del', bridgeName, 'type', 'bridge'])
    if rc != 0:
        raise EnvironmentError(
            'Failed to remove ephemeral dummy bridge. Err: %s' % err
        )


def addBridgeToLibvirt(bridgeName):
    conn = libvirtconnection.get(None, False)
    if bridgeName not in conn.listNetworks():
        conn.networkCreateXML(
            '''<network><name>%s</name><forward mode='bridge'/><bridge '''
            '''name='%s'/></network>''' % (bridgeName, bridgeName))


def removeBridgeFromLibvirt(bridgeName):
    dummy_network = _getLibvirtNetworkByName(bridgeName)
    if dummy_network and dummy_network.isActive():
        dummy_network.destroy()


def _getLibvirtNetworkByName(networkName):
    conn = libvirtconnection.get(killOnFailure=False)
    try:
        return conn.networkLookupByName(networkName)
    except libvirtError as e:
        if e.get_error_code() == VIR_ERR_NO_NETWORK:
            return None
        raise


@expose('dummybr')
def create_dummybr_deprecated(*args):
    create_dummybr(*args)


@expose('dummybr-create')
def create_dummybr(*args):

    if len(args) > 1:
        raise ExtraArgsError()

    if not os.path.exists('/sys/class/net/%s' % DUMMY_BRIDGE):
        createEphemeralBridge(DUMMY_BRIDGE)
    addBridgeToLibvirt(DUMMY_BRIDGE)


@expose('dummybr-remove')
def remove_dummybr(*args):

    if len(args) > 1:
        raise ExtraArgsError()

    if os.path.exists('/sys/class/net/%s' % DUMMY_BRIDGE):
        removeEphemeralBridge(DUMMY_BRIDGE)
    removeBridgeFromLibvirt(DUMMY_BRIDGE)
