#!/usr/bin/env python
import os
import sys

Debug = False

netname = 'H'

# Interface tupel ( subnet, uml_switch_id )
net = [{'name':'host1', 'role':'generic', 'interface':[(1,1),(1,2)]},
       {'name':'bridge1', 'role':'bridge', 'interface':[(1,1),(1,2)]},
       {'name':'bridge2', 'role':'bridge', 'interface':[(1,1),(1,2)]},
       {'name':'bridge3', 'role':'bridge', 'interface':[(1,1),(1,2)]}
      ]


def create_switches(name, num):
    "Create 'num' switches in netork 'name')"
    for i in range(1,num+1):
        cmd = 'switch start %s_switch_%d  -hub' % (netname,i)
        execute(cmd)

def destroy_switches(name, num):
    "Destroy 'num' switches in network 'name'"
    for i in range(1,num+1):
        cmd = 'switch stop %s_switch_%d' % (netname,i)
        execute(cmd)

def create_hosts(network):
    """"
    Create hosts, based on list of dicts in network
    These dicts should at least contain:
    'name' : string                         Name for the host
    'role' : 'generic'|'bridge'|'router'    It's role
    'interface' : list of (x,y)
        where x = network segment (10.0.x.i)
              y = uml-switch to connect to
    """
    for machine in network:
        # Setup the base for the system
        cmd = 'MYDIR=${TMPDIR:-/tmp}/${USER}; cd ${MYDIR};'
        cmd += ' screen -dmS %s linux umid=%s mem=10m \\\n' % (machine['name'], machine['name'])
        cmd += ' root=/dev/root rootflags=/snb/linux/i386/var/uml-root-fs rootfstype=hostfs \\\n'
        # Create network interfaces for the machine
        for interf in range(0,len(machine['interface'])):
            net, swi = machine['interface'][interf]
            cmd += ' eth%d=daemon,,unix,${HOME}/.uml/%s_switch_%d.sock \\\n' % (interf, netname, swi)
            cmd += ' ip_eth%d=10.0.%d.%d \\\n' % (interf, net, (network.index(machine)+1))
            cmd += ' mask_eth%d=255.255.255.0 \\\n' % interf
            cmd += ' bc_eth%d=10.0.%d.255 \\\n' % (interf, net)
        # If a gateway is declared, add it to cmd (there can be only one)
        if machine.has_key('gateway'):
            cmd += ' gateway=10.0.%d.%d \\\n' % (machine['interface'][0], machine['gateway'])
        # Last but not least, add a role keyword to the params
        cmd += ' role=%s\n' % machine['role']
        execute(cmd)

def destroy_hosts(network):
    "Destroy all the hosts in the network"
    for machine in network:
        cmd = 'uml_mconsole %s halt' % machine['name']
        execute(cmd)

def max_switches(network):
    "Find out how many switches there are in 'network'"
    num = 0
    for machine in network:
        for interf in machine['interface']:
            if interf[1] > num:
                num = interf[1]
    return num

def execute(cmd):
    if Debug:
        print cmd
    os.system(cmd)

if __name__ == "__main__":
    if len(sys.argv)==1:
        print "Please supply either 'start', 'stop' or 'test'"
    elif sys.argv[1]=='start':
        os.system('MYDIR=${TMPDIR:-/tmp}/${USER}; mkdir -p ${MYDIR}')
        create_switches(netname, max_switches(net))
        create_hosts(net)
    elif sys.argv[1]=='stop':
        destroy_switches(netname, max_switches(net))
        destroy_hosts(net)
        os.system('MYDIR=${TMPDIR:-/tmp}/${USER}; rm -fr ${MYDIR}')
    elif sys.argv[1]=='test':
        if len(sys.argv) < 2:
            print "Please supply either 'start' or 'stop' after 'test'"
        Debug = True
        if sys.argv[2]=='start':
            create_switches(netname, max_switches(net))
            print '\n'
            create_hosts(net)
        elif sys.argv[2]=='stop':
            destroy_switches(netname, max_switches(net))
            print '\n'
            destroy_hosts(net)
        else:
            print "Please supply either 'start' or 'stop' after 'test'"
    else:
        print "Please supply either 'start', 'stop' or 'test'"
