#!/usr/bin/python
import os
import re
from optparse import OptionParser

from ipaddress import ip_network
from mininet.node import RemoteController, OVSBridge, Host, OVSSwitch
from mininet.link import TCLink
from mininet.log import setLogLevel
from mininet.net import Mininet
from mininet.topo import Topo
from mininet.nodelib import NAT
from mininet.cli import CLI

from routinglib import BgpRouter
from trellislib import TrellisHost, DhcpRelay
from functools import partial

from bmv2 import ONOSBmv2Switch
from stratum import StratumBmv2Switch

# Parse command line options and dump results
def parseOptions():
    "Parse command line options"
    parser = OptionParser()
    parser.add_option( '--spine', dest='spine', type='int', default=2,
                       help='number of spine switches, default=2' )
    parser.add_option( '--leaf', dest='leaf', type='int', default=2,
                       help='number of leaf switches, default=2' )
    parser.add_option( '--fanout', dest='fanout', type='int', default=2,
                       help='number of hosts per leaf switch, default=2' )
    parser.add_option( '--onos-ip', dest='onosIp', type='str', default='',
                       help='IP address list of ONOS instances, separated by comma(,). Overrides --onos option' )
    parser.add_option( '--ipv6', action="store_true", dest='ipv6',
                       help='hosts are capable to use also ipv6' )
    parser.add_option( '--dual-homed', action="store_true", dest='dualhomed', default=False,
                       help='True if the topology is dual-homed, default=False' )
    parser.add_option( '--vlan', dest='vlan', type='str', default='',
                       help='list of vlan id for hosts, separated by comma(,).'
                            'Empty or id with 0 will be unconfigured.' )
    parser.add_option( '--dhcp-client', action="store_true", dest='dhcpClient', default=False,
                       help='Set hosts as DhcpClient if True' )
    parser.add_option( '--dhcp-relay', action="store_true", dest='dhcpRelay', default=False,
                       help='Connect half of the hosts to switch indirectly (via DHCP relay) if True' )
    parser.add_option( '--multiple-dhcp-server', action="store_true", dest='multipleServer', default=False,
                       help='Use another DHCP server for indirectly connected DHCP clients if True' )
    parser.add_option( '--remote-dhcp-server', action="store_true", dest='remoteServer', default=False,
                       help='Connect DHCP server indirectly (via gateway) if True' )
    parser.add_option( '--switch', dest='switch', type='str', default='ovs',
                       help='Switch type: ovs, bmv2 (with fabric.p4), stratum' )
    ( options, args ) = parser.parse_args()
    return options, args

opts, args = parseOptions()

IP6_SUBNET_CLASS = 120
IP4_SUBNET_CLASS = 24
FABRIC_PIPECONF = "org.onosproject.pipelines.fabric"

SWITCH_TO_PARAMS_DICT = {
    "ovs": dict(cls=OVSSwitch),
    "bmv2": dict(cls=ONOSBmv2Switch, pipeconf=FABRIC_PIPECONF),
    "stratum": dict(cls=StratumBmv2Switch, pipeconf=FABRIC_PIPECONF, loglevel='debug')
}
if opts.switch not in SWITCH_TO_PARAMS_DICT:
    raise Exception("Unknown switch type '%s'" % opts.switch)
SWITCH_PARAMS = SWITCH_TO_PARAMS_DICT[opts.switch]

# TODO: DHCP support
class IpHost( Host ):

    def __init__( self, name, *args, **kwargs ):
        super( IpHost, self ).__init__( name, *args, **kwargs )
        gateway = re.split( '\.|/', kwargs[ 'ip' ] )
        gateway[ 3 ] = '254'
        self.gateway = '.'.join( gateway[ 0:4 ] )

    def config( self, **kwargs ):
        Host.config( self, **kwargs )
        mtu = "ifconfig " + self.name + "-eth0 mtu 1490"
        self.cmd( mtu )
        self.cmd( 'ip route add default via %s' % self.gateway )

class DualHomedIpHost(IpHost):
    def __init__(self, name, *args, **kwargs):
        super(DualHomedIpHost, self).__init__(name, **kwargs)
        self.bond0 = None

    def config(self, **kwargs):
        super(DualHomedIpHost, self).config(**kwargs)
        intf0 = self.intfs[0].name
        intf1 = self.intfs[1].name
        self.bond0 = "%s-bond0" % self.name
        self.cmd('modprobe bonding')
        self.cmd('ip link add %s type bond' % self.bond0)
        self.cmd('ip link set %s down' % intf0)
        self.cmd('ip link set %s down' % intf1)
        self.cmd('ip link set %s master %s' % (intf0, self.bond0))
        self.cmd('ip link set %s master %s' % (intf1, self.bond0))
        self.cmd('ip addr flush dev %s' % intf0)
        self.cmd('ip addr flush dev %s' % intf1)
        self.cmd('ip link set %s up' % self.bond0)

    def terminate(self, **kwargs):
        self.cmd('ip link set %s down' % self.bond0)
        self.cmd('ip link delete %s' % self.bond0)
        self.cmd('kill -9 `cat %s`' % self.pidFile)
        self.cmd('rm -rf %s' % self.pidFile)
        super(DualHomedIpHost, self).terminate()


# TODO: Implement IPv6 support
class DualHomedLeafSpineFabric (Topo) :
    def __init__(self, spine = 2, leaf = 2, fanout = 2, vlan_id = [], ipv6 = False,
                 dhcp_client = False, dhcp_relay = False,
                 multiple_server = False, remote_server = False, **opts):
        # TODO: add support to dhcp_relay, multiple_server and remote_server
        Topo.__init__(self, **opts)
        spines = dict()
        leafs = dict()

        # leaf should be 2 or 4

        # calculate the subnets to use and set options
        linkopts = dict( bw=100 )
        # Create spine switches
        for s in range(spine):
            spines[s] = self.addSwitch( 'spine10%s' % (s + 1),
                                        dpid="00000000010%s" % (s + 1),
                                        **SWITCH_PARAMS )

        # Create leaf switches
        for ls in range(leaf):
            leafs[ls] = self.addSwitch( 'leaf%s' % (ls + 1),
                                        dpid="00000000000%s" % (ls + 1),
                                        **SWITCH_PARAMS )

            # Connect leaf to all spines with dual link
            for s in range( spine ):
                switch = spines[ s ]
                self.addLink(leafs[ls], switch, **linkopts)
                self.addLink(leafs[ls], switch, **linkopts)

            # Add hosts after paired ToR switches are added.
            if ls % 2 == 0:
                continue

            # Add leaf-leaf link
            self.addLink(leafs[ls], leafs[ls-1])

            dual_ls = ls / 2
            # Add hosts
            for f in range(fanout):
                name = 'h%s%s' % (dual_ls * fanout + f + 1, "v6" if ipv6 else "")
                if ipv6:
                    ips = ['2000::%d0%d/%d' % (dual_ls+2, f+1, IP6_SUBNET_CLASS)]
                    gateway = '2000::%dff' % (dual_ls+2)
                    mac = '00:bb:00:00:00:%02x' % (dual_ls * fanout + f + 1)
                else:
                    ips = ['10.0.%d.%d/%d' % (dual_ls+2, f+1, IP4_SUBNET_CLASS)]
                    gateway = '10.0.%d.254' % (dual_ls+2)
                    mac = '00:aa:00:00:00:%02x' % (dual_ls * fanout + f + 1)
                host = self.addHost( name=name, cls=TrellisHost, ips=ips, gateway=gateway, mac=mac,
                                     vlan=vlan_id[ dual_ls*fanout + f ] if vlan_id[dual_ls * fanout + f] != 0 else None,
                                     dhcpClient=dhcp_client, ipv6=ipv6, dualHomed=True )
                self.addLink(host, leafs[ls], **linkopts)
                self.addLink(host, leafs[ls-1], **linkopts)

        last_ls = leafs[leaf-2]
        last_paired_ls = leafs[leaf-1]
        # Create common components
        # Control plane switch (for DHCP servers)
        cs1 = self.addSwitch('cs1', cls=OVSBridge)
        self.addLink(cs1, last_ls)

        # Control plane switch (for quagga fpm)
        cs0 = self.addSwitch('cs0', cls=OVSBridge)

        # Control plane NAT (for quagga fpm)
        nat = self.addHost('nat', cls=NAT,
                           ip='172.16.0.1/12',
                           subnet=str(ip_network(u'172.16.0.0/12')), inNamespace=False)
        self.addLink(cs0, nat)

        # Internal Quagga bgp1
        intfs = {'bgp1-eth0': {'ipAddrs': ['10.0.1.2/24', '2000::102/120'], 'mac': '00:88:00:00:00:03'},
                 'bgp1-eth1': {'ipAddrs': ['172.16.0.2/12']}}
        bgp1 = self.addHost('bgp1', cls=BgpRouter,
                            interfaces=intfs,
                            quaggaConfFile='./bgpdbgp1.conf',
                            zebraConfFile='./zebradbgp1.conf')
        self.addLink(bgp1, last_ls)
        self.addLink(bgp1, cs0)

        # Internal Quagga bgp2
        intfs = {'bgp2-eth0': [{'ipAddrs': ['10.0.5.2/24', '2000::502/120'], 'mac': '00:88:00:00:00:04', 'vlan': '150'},
                               {'ipAddrs': ['10.0.6.2/24', '2000::602/120'], 'mac': '00:88:00:00:00:04', 'vlan': '160'}],
                 'bgp2-eth1': {'ipAddrs': ['172.16.0.4/12']}}
        bgp2 = self.addHost('bgp2', cls=BgpRouter,
                            interfaces=intfs,
                            quaggaConfFile='./bgpdbgp2.conf',
                            zebraConfFile='./zebradbgp2.conf')
        self.addLink(bgp2, last_paired_ls)
        self.addLink(bgp2, cs0)

        # External Quagga r1
        intfs = {'r1-eth0': {'ipAddrs': ['10.0.1.1/24', '2000::101/120'], 'mac': '00:88:00:00:00:01'},
                 'r1-eth1': {'ipAddrs': ['10.0.5.1/24', '2000::501/120'], 'mac': '00:88:00:00:00:11'},
                 'r1-eth2': {'ipAddrs': ['10.0.99.1/16']}}
        r1 = self.addHost('r1', cls=BgpRouter,
                            interfaces=intfs,
                            quaggaConfFile='./bgpdr1.conf')
        self.addLink(r1, last_ls)
        self.addLink(r1, last_paired_ls)

        # External IPv4 Host behind r1
        rh1 = self.addHost('rh1', cls=TrellisHost, ips=['10.0.99.2/24'], gateway='10.0.99.1')
        self.addLink(r1, rh1)

        # External Quagga r2
        intfs = {'r2-eth0': {'ipAddrs': ['10.0.6.1/24', '2000::601/120'], 'mac': '00:88:00:00:00:02'},
                 'r2-eth1': {'ipAddrs': ['10.0.7.1/24', '2000::701/120'], 'mac': '00:88:00:00:00:22'},
                 'r2-eth2': {'ipAddrs': ['10.0.99.1/16']}}
        r2 = self.addHost('r2', cls=BgpRouter,
                            interfaces=intfs,
                            quaggaConfFile='./bgpdr2.conf')
        self.addLink(r2, last_ls)
        self.addLink(r2, last_paired_ls)

        # External IPv4 Host behind r2
        rh2 = self.addHost('rh2', cls=TrellisHost, ips=['10.0.99.2/24'], gateway='10.0.99.1')
        self.addLink(r2, rh2)

        # DHCP server
        if ipv6:
            dhcp = self.addHost('dhcp', cls=TrellisHost, mac='00:99:00:00:00:01',
                                ips=['2000::3fd/120'], gateway='2000::3ff',
                                dhcpServer=True, ipv6=True)
            self.addLink(dhcp, cs1)
        else:
            dhcp = self.addHost('dhcp', cls=TrellisHost, mac='00:99:00:00:00:01',
                                ips=['10.0.3.253/24'], gateway='10.0.3.254',
                                dhcpServer=True)
            self.addLink(dhcp, cs1)


class LeafSpineFabric (Topo) :
    def __init__(self, spine = 2, leaf = 2, fanout = 2, vlan_id = [], ipv6 = False,
                 dhcp_client = False, dhcp_relay = False,
                 multiple_server = False, remote_server = False, **opts):
        Topo.__init__(self, **opts)
        spines = dict()
        leafs = dict()

        # TODO: support IPv6 hosts
        linkopts = dict( bw=100 )

        # Create spine switches
        for s in range(spine):
            spines[s] = self.addSwitch( 'spine10%s' % (s + 1),
                                        dpid="00000000010%s" % (s + 1),
                                        **SWITCH_PARAMS )

        # Create leaf switches
        for ls in range(leaf):
            leafs[ls] = self.addSwitch( 'leaf%s' % (ls + 1),
                                        dpid="00000000000%s" % (ls + 1),
                                        **SWITCH_PARAMS )

            # Connect leaf to all spines
            for s in range( spine ):
                switch = spines[ s ]
                self.addLink( leafs[ ls ], switch, **linkopts )

            # If dual-homed ToR, add hosts only when adding second switch at each edge-pair
            # When the number of leaf switches is odd, leave the last switch as a single ToR

            # Add hosts
            for f in range(fanout):
                name = 'h%s%s' % (ls * fanout + f + 1, "v6" if ipv6 else "")
                if ipv6:
                    ips = ['2000::%d0%d/%d' % (ls+2, f+1, IP6_SUBNET_CLASS)]
                    gateway = '2000::%dff' % (ls+2)
                    mac = '00:bb:00:00:00:%02x' % (ls * fanout + f + 1)
                else:
                    ips = ['10.0.%d.%d/%d' % (ls+2, f+1, IP4_SUBNET_CLASS)]
                    gateway = '10.0.%d.254' % (ls+2)
                    mac = '00:aa:00:00:00:%02x' % (ls * fanout + f + 1)
                host = self.addHost( name=name, cls=TrellisHost, ips=ips, gateway=gateway, mac=mac,
                                     vlan=vlan_id[ ls*fanout + f ] if vlan_id[ls * fanout + f] != 0 else None,
                                     dhcpClient=dhcp_client, ipv6=ipv6 )
                if dhcp_relay and f % 2:
                    relayIndex = ls * fanout + f + 1
                    if ipv6:
                        intfs = {
                            'relay%s-eth0' % relayIndex: { 'ipAddrs': ['2000::%dff/%d' % (leaf + ls + 2, IP6_SUBNET_CLASS)] },
                            'relay%s-eth1' % relayIndex: { 'ipAddrs': ['2000::%d5%d/%d' % (ls + 2, f, IP6_SUBNET_CLASS)] }
                        }
                        if remote_server:
                            serverIp = '2000::99fd'
                        elif multiple_server:
                            serverIp = '2000::3fc'
                        else:
                            serverIp = '2000::3fd'
                        dhcpRelay = self.addHost(name='relay%s' % relayIndex, cls=DhcpRelay, serverIp=serverIp,
                                                 gateway='2000::%dff' % (ls+2), interfaces=intfs)
                    else:
                        intfs = {
                            'relay%s-eth0' % relayIndex: { 'ipAddrs': ['10.0.%d.254/%d' % (leaf + ls + 2, IP4_SUBNET_CLASS)] },
                            'relay%s-eth1' % relayIndex: { 'ipAddrs': ['10.0.%d.%d/%d' % (ls + 2, f + 99, IP4_SUBNET_CLASS)] }
                        }
                        if remote_server:
                            serverIp = '10.0.99.3'
                        elif multiple_server:
                            serverIp = '10.0.3.252'
                        else:
                            serverIp = '10.0.3.253'
                        dhcpRelay = self.addHost(name='relay%s' % relayIndex, cls=DhcpRelay, serverIp=serverIp,
                                                 gateway='10.0.%d.254' % (ls+2), interfaces=intfs)
                    self.addLink(host, dhcpRelay, **linkopts)
                    self.addLink(dhcpRelay, leafs[ls], **linkopts)
                else:
                    self.addLink(host, leafs[ls], **linkopts)

        last_ls = leafs[leaf-1]
        # Create common components
        # Control plane switch (for DHCP servers)
        cs1 = self.addSwitch('cs1', cls=OVSBridge)
        self.addLink(cs1, last_ls)

        # Control plane switch (for quagga fpm)
        cs0 = self.addSwitch('cs0', cls=OVSBridge)

        # Control plane NAT (for quagga fpm)
        nat = self.addHost('nat', cls=NAT,
                           ip='172.16.0.1/12',
                           subnet=str(ip_network(u'172.16.0.0/12')), inNamespace=False)
        self.addLink(cs0, nat)

        # Internal Quagga bgp1
        intfs = {'bgp1-eth0': {'ipAddrs': ['10.0.1.2/24', '2000::102/120'], 'mac': '00:88:00:00:00:02'},
                 'bgp1-eth1': {'ipAddrs': ['172.16.0.2/12']}}
        bgp1 = self.addHost('bgp1', cls=BgpRouter,
                            interfaces=intfs,
                            quaggaConfFile='./bgpdbgp1.conf',
                            zebraConfFile='./zebradbgp1.conf')
        self.addLink(bgp1, last_ls)
        self.addLink(bgp1, cs0)

        # External Quagga r1
        intfs = {'r1-eth0': {'ipAddrs': ['10.0.1.1/24', '2000::101/120'], 'mac': '00:88:00:00:00:01'},
                 'r1-eth1': {'ipAddrs': ['10.0.99.1/16']},
                 'r1-eth2': {'ipAddrs': ['2000::9901/120']}}
        r1 = self.addHost('r1', cls=BgpRouter,
                            interfaces=intfs,
                            quaggaConfFile='./bgpdr1.conf')
        self.addLink(r1, last_ls)

        # External switch behind r1
        rs0 = self.addSwitch('rs0', cls=OVSBridge)
        self.addLink(r1, rs0)

        # External IPv4 Host behind r1
        rh1 = self.addHost('rh1', cls=TrellisHost, ips=['10.0.99.2/24'], gateway='10.0.99.1')
        self.addLink(r1, rh1)

        # External IPv6 Host behind r1
        rh1v6 = self.addHost('rh1v6', cls=TrellisHost, ips=['2000::9902/120'], gateway='2000::9901')
        self.addLink(r1, rh1v6)

        # DHCP server
        if ipv6:
            if remote_server:
                dhcp = self.addHost('dhcp', cls=TrellisHost, mac='00:99:00:00:00:01',
                                    ips=['2000::99fd/120'], gateway='2000::9901',
                                    dhcpServer=True, ipv6=True)
                self.addLink(rs0, dhcp)
            else:
                dhcp = self.addHost('dhcp', cls=TrellisHost, mac='00:99:00:00:00:01',
                                    ips=['2000::3fd/120'], gateway='2000::3ff',
                                    dhcpServer=True, ipv6=True)
                self.addLink(dhcp, cs1)
                if multiple_server:
                    dhcp2 = self.addHost('dhcp2', cls=TrellisHost, mac='00:99:00:00:00:02',
                                         ips=['2000::3fc/120'], gateway='2000::3ff',
                                         dhcpServer=True, ipv6=True)
                    self.addLink(dhcp2, cs1)
        else:
            if remote_server:
                dhcp = self.addHost('dhcp', cls=TrellisHost, mac='00:99:00:00:00:01',
                                    ips=['10.0.99.3/24'], gateway='10.0.99.1',
                                    dhcpServer=True)
                self.addLink(rs0, dhcp)
            else:
                dhcp = self.addHost('dhcp', cls=TrellisHost, mac='00:99:00:00:00:01',
                                    ips=['10.0.3.253/24'], gateway='10.0.3.254',
                                    dhcpServer=True)
                self.addLink(dhcp, cs1)
                if multiple_server:
                    dhcp2 = self.addHost('dhcp2', cls=TrellisHost, mac='00:99:00:00:00:02',
                                         ips=['10.0.3.252/24'], gateway='10.0.3.254',
                                         dhcpServer=True)
                    self.addLink(dhcp2, cs1)

def config( opts ):
    spine = opts.spine
    leaf = opts.leaf
    fanout = opts.fanout
    dualhomed = opts.dualhomed
    if opts.vlan == '':
        vlan = [0] * (((leaf / 2) if dualhomed else leaf) * fanout)
    else:
        vlan = [int(vlan_id) if vlan_id != '' else 0 for vlan_id in opts.vlan.split(',')]

    if opts.onosIp != '':
        controllers = opts.onosIp.split( ',' )
    else:
        controllers = ['127.0.0.1']

    if len(vlan) != ((leaf / 2) if dualhomed else leaf ) * fanout:
        print "Invalid vlan configuration is given."
        return

    if dualhomed:
        if leaf % 2 == 1 or leaf == 0:
            print "Even number of leaf switches (at least two) are needed to build dual-homed topology."
            return
        else:
            topo = DualHomedLeafSpineFabric(spine=spine, leaf=leaf, fanout=fanout, vlan_id=vlan,
                                            ipv6=opts.ipv6,
                                            dhcp_client=opts.dhcpClient,
                                            dhcp_relay=opts.dhcpRelay,
                                            multiple_server=opts.multipleServer,
                                            remote_server=opts.remoteServer)
    else:
        topo = LeafSpineFabric(spine=spine, leaf=leaf, fanout=fanout, vlan_id=vlan, ipv6=opts.ipv6,
                               dhcp_client=opts.dhcpClient,
                               dhcp_relay=opts.dhcpRelay,
                               multiple_server=opts.multipleServer,
                               remote_server=opts.remoteServer)

    net = Mininet( topo=topo, link=TCLink, build=False,
                   controller=None, autoSetMacs=True )
    i = 0
    for ip in controllers:
        net.addController( "c%s" % ( i ), controller=RemoteController, ip=ip )
        i += 1
    net.build()
    net.start()
    CLI( net )
    net.stop()

if __name__ == '__main__':
    setLogLevel('info')
    config(opts)
    os.system('sudo mn -c')
