#!/usr/bin/python

import os
import sys
import json
import argparse
from collections import OrderedDict

TEMP_NETCFG_FILE = '/tmp/bmv2-demo-cfg.json'
BASE_LONGITUDE = -115
SWITCH_BASE_LATITUDE = 25
HOST_BASE_LATITUDE = 28
BASE_SHIFT = 8
VLAN_NONE = -1
DEFAULT_SW_BW = 50
DEFAULT_HOST_BW = 25

if 'ONOS_ROOT' not in os.environ:
    print "Environment var $ONOS_ROOT not set"
    exit()
else:
    ONOS_ROOT = os.environ["ONOS_ROOT"]
    sys.path.append(ONOS_ROOT + "/tools/dev/mininet")
if 'RUN_PACK_PATH' not in os.environ:
    print "Environment var $RUN_PACK_PATH not set"
    exit()
else:
    RUN_PACK_PATH = os.environ["RUN_PACK_PATH"]

from onos import ONOSCluster, ONOSCLI
from bmv2 import ONOSBmv2Switch, ONOSHost

from itertools import combinations
from time import sleep
from subprocess import call

from mininet.cli import CLI
from mininet.link import TCLink
from mininet.log import setLogLevel
from mininet.net import Mininet
from mininet.node import RemoteController, Host
from mininet.topo import Topo


def getCmdBg(cmd, logfile="/dev/null"):
    return "{} > {} 2>&1 &".format(cmd, logfile)


class ClosTopo(Topo):
    """2 stage Clos topology"""

    def __init__(self, args, **opts):
        # Initialize topology and default options
        Topo.__init__(self, **opts)

        bmv2SwitchIds = []
        for row in (1, 2):
            for col in range(1, args.size + 1):
                bmv2SwitchIds.append("s%d%d" % (row, col))

        bmv2Switches = {}

        for switchId in bmv2SwitchIds:
            deviceId = int(switchId[1:])
            # Use first number in device id to calculate latitude (row number),
            # use second to calculate longitude (column number)
            latitude = SWITCH_BASE_LATITUDE + (deviceId // 10) * BASE_SHIFT
            longitude = BASE_LONGITUDE + (deviceId % 10) * BASE_SHIFT

            bmv2Switches[switchId] = self.addSwitch(switchId,
                                                    cls=ONOSBmv2Switch,
                                                    loglevel=args.log_level,
                                                    deviceId=deviceId,
                                                    netcfg=True,
                                                    netcfgDelay=0.5,
                                                    longitude=longitude,
                                                    latitude=latitude,
                                                    pipeconfId=args.pipeconf_id)

        for i in range(1, args.size + 1):
            for j in range(1, args.size + 1):
                if i == j:
                    self.addLink(bmv2Switches["s1%d" % i],
                                 bmv2Switches["s2%d" % j],
                                 cls=TCLink, bw=DEFAULT_SW_BW)
                    if args.with_imbalanced_striping:
                        # 2 links
                        self.addLink(bmv2Switches["s1%d" % i],
                                     bmv2Switches["s2%d" % j],
                                     cls=TCLink, bw=DEFAULT_SW_BW)
                else:
                    self.addLink(bmv2Switches["s1%d" % i],
                                 bmv2Switches["s2%d" % j],
                                 cls=TCLink, bw=DEFAULT_SW_BW)

        for hostId in range(1, args.size + 1):
            host = self.addHost("h%d" % hostId,
                                cls=DemoHost,
                                ip="10.0.0.%d/24" % hostId,
                                mac='00:00:00:00:00:%02x' % hostId)
            self.addLink(host, bmv2Switches["s1%d" % hostId],
                         cls=TCLink, bw=DEFAULT_HOST_BW)


class DemoHost(ONOSHost):
    """Demo host"""

    def __init__(self, name, **params):
        ONOSHost.__init__(self, name, **params)
        self.exectoken = "/tmp/mn-exec-token-host-%s" % name
        self.cmd("touch %s" % self.exectoken)

    def startPingBg(self, h):
        self.cmd(self.getInfiniteCmdBg("ping -i0.5 %s" % h.IP()))
        self.cmd(self.getInfiniteCmdBg("arping -w5000000 %s" % h.IP()))

    def startIperfServer(self):
        self.cmd(self.getInfiniteCmdBg("iperf -s -u"))

    def startIperfClient(self, h, flowBw="512k", numFlows=5, duration=5):
        iperfCmd = "iperf -c{} -u -b{} -P{} -t{}".format(
            h.IP(), flowBw, numFlows, duration)
        self.cmd(self.getInfiniteCmdBg(iperfCmd, delay=0))

    def stop(self, **kwargs):
        self.cmd("killall iperf")
        self.cmd("killall ping")
        self.cmd("killall arping")

    def describe(self):
        print "**********"
        print self.name
        print "default interface: %s\t%s\t%s" % (
            self.defaultIntf().name,
            self.defaultIntf().IP(),
            self.defaultIntf().MAC()
        )
        print "**********"

    def getInfiniteCmdBg(self, cmd, logfile="/dev/null", delay=1):
        return "(while [ -e {} ]; " \
               "do {}; " \
               "sleep {}; " \
               "done;) > {} 2>&1 &".format(self.exectoken, cmd, delay, logfile)


def generateNetcfg(onosIp, net, args):
    netcfg = OrderedDict()

    netcfg['hosts'] = {}
    netcfg['devices'] = {}
    netcfg['links'] = {}

    if args.full_netcfg:
        # Device configs
        for sw in net.switches:
            srcIp = sw.getSourceIp(onosIp)
            netcfg['devices'][sw.onosDeviceId] = sw.getDeviceConfig(srcIp)

    hostLocations = {}
    for link in net.links:
        switchPort = link.intf1.name.split('-')
        sw1Name = switchPort[0]  # s11
        port1Name = switchPort[1]  # eth0
        port1 = port1Name[3:]
        switchPort = link.intf2.name.split('-')
        sw2Name = switchPort[0]
        port2Name = switchPort[1]
        port2 = port2Name[3:]
        sw1 = net[sw1Name]
        sw2 = net[sw2Name]
        if isinstance(sw1, Host):
            # record host location and ignore it
            # e.g. {'h1': 'device:bmv2:11'}
            hostLocations[sw1.name] = '%s/%s' % (sw2.onosDeviceId, port2)
            continue

        if isinstance(sw2, Host):
            # record host location and ignore it
            # e.g. {'h1': 'device:bmv2:11'}
            hostLocations[sw2.name] = '%s/%s' % (sw1.onosDeviceId, port1)
            continue

        if args.full_netcfg:
            # Link configs
            for linkId in ('%s/%s-%s/%s' % (sw1.onosDeviceId, port1,
                                            sw2.onosDeviceId, port2),
                           '%s/%s-%s/%s' % (sw2.onosDeviceId, port2,
                                            sw1.onosDeviceId, port1)):
                netcfg['links'][linkId] = {
                    'basic': {
                        'type': 'DIRECT',
                        'bandwidth': DEFAULT_SW_BW
                    }
                }

    # Host configs
    longitude = BASE_LONGITUDE
    for host in net.hosts:
        longitude = longitude + BASE_SHIFT
        hostDefaultIntf = host.defaultIntf()
        hostMac = host.MAC(hostDefaultIntf)
        hostIp = host.IP(hostDefaultIntf)
        hostId = '%s/%d' % (hostMac, VLAN_NONE)
        location = hostLocations[host.name]

        # use host Id to generate host location
        hostConfig = {
            'basic': {
                'locations': [location],
                'ips': [hostIp],
                'name': host.name,
                'latitude': HOST_BASE_LATITUDE,
                'longitude': longitude
            }
        }
        netcfg['hosts'][hostId] = hostConfig

    if args.full_netcfg:
        netcfg["apps"] = {
            "org.onosproject.core": {
                "core": {
                    "linkDiscoveryMode": "STRICT"
                }
            }
        }

    print "Writing network config to %s" % TEMP_NETCFG_FILE
    with open(TEMP_NETCFG_FILE, 'w') as tempFile:
        json.dump(netcfg, tempFile, indent=4)


def main(args):
    if not args.onos_ip:
        controller = ONOSCluster('c0', 3)
        onosIp = controller.nodes()[0].IP()
    else:
        controller = RemoteController('c0', ip=args.onos_ip)
        onosIp = args.onos_ip

    topo = ClosTopo(args)

    net = Mininet(topo=topo, build=False, controller=[controller])

    net.build()
    net.start()

    print "Network started"

    # Always generate background pings.
    sleep(3)
    for (h1, h2) in combinations(net.hosts, 2):
        h1.startPingBg(h2)
        h2.startPingBg(h1)

    print "Background ping started"

    for h in net.hosts:
        h.startIperfServer()

    print "Iperf servers started"

    if args.bg_traffic:
        sleep(4)
        print "Starting iperf clients..."
        net.hosts[0].startIperfClient(net.hosts[-1], flowBw="400k",
                                      numFlows=50, duration=10)

    generateNetcfg(onosIp, net, args)

    if args.netcfg_sleep > 0:
        print "Waiting %d seconds before pushing config to ONOS..." \
              % args.netcfg_sleep
        sleep(args.netcfg_sleep)

    print "Pushing config to ONOS..."
    call(("%s/onos-netcfg" % RUN_PACK_PATH, onosIp, TEMP_NETCFG_FILE))

    if not args.onos_ip:
        ONOSCLI(net)
    else:
        CLI(net)

    net.stop()
    call(("rm", "-f", TEMP_NETCFG_FILE))


if __name__ == '__main__':
    parser = argparse.ArgumentParser(
        description='BMv2 mininet demo script (2-stage Clos topology)')
    parser.add_argument('--onos-ip', help='ONOS-BMv2 controller IP address',
                        type=str, action="store", required=False)
    parser.add_argument('--size', help='Number of leaf/spine switches',
                        type=int, action="store", required=False, default=2)
    parser.add_argument('--with-imbalanced-striping',
                        help='Topology with imbalanced striping',
                        type=bool, action="store", required=False,
                        default=False)
    parser.add_argument('--pipeconf-id', help='Pipeconf ID for switches',
                        type=str, action="store", required=False, default='')
    parser.add_argument('--netcfg-sleep',
                        help='Seconds to wait before pushing config to ONOS',
                        type=int, action="store", required=False, default=5)
    parser.add_argument('--log-level', help='BMv2 log level',
                        type=str, action="store", required=False,
                        default='warn')
    parser.add_argument('--full-netcfg',
                        help='Generate full netcfg JSON with links and devices',
                        type=bool, action="store", required=False,
                        default=False)
    parser.add_argument('--bg-traffic',
                        help='Starts background traffic',
                        type=bool, action="store", required=False,
                        default=False)
    setLogLevel('info')
    main(parser.parse_args())
