import os
import socket
import re
import json
import threading
import urllib2

import time
from contextlib import closing

from mininet.log import info, warn, error
from mininet.node import Switch, Host

if 'ONOS_ROOT' not in os.environ:
    error("ERROR: environment var $ONOS_ROOT not set")
    exit()

SIMPLE_SWITCH_GRPC = 'simple_switch_grpc'
ONOS_ROOT = os.environ["ONOS_ROOT"]
PKT_BYTES_TO_DUMP = 80
VALGRIND_PREFIX = 'valgrind --leak-check=yes'
SWITCH_START_TIMEOUT = 5  # seconds
BMV2_LOG_LINES = 5


def parseBoolean(value):
    if value in ['1', 1, 'true', 'True']:
        return True
    else:
        return False


def pickUnusedPort():
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.bind(('localhost', 0))
    addr, port = s.getsockname()
    s.close()
    return port


def writeToFile(path, value):
    with open(path, "w") as f:
        f.write(str(value))


def watchDog(sw):
    while True:
        if sw.stopped:
            return
        with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as s:
            if s.connect_ex(('127.0.0.1', sw.grpcPort)) == 0:
                time.sleep(1)
            else:
                warn("\n*** WARN: BMv2 instance %s (%s) died!\n"
                     % (sw.deviceId, sw.name))
                sw.printBmv2Log()
                print ("-" * 80) + "\n"
                return


class ONOSHost(Host):
    def __init__(self, name, inNamespace=True, **params):
        Host.__init__(self, name, inNamespace=inNamespace, **params)

    def config(self, **params):
        r = super(Host, self).config(**params)
        for off in ["rx", "tx", "sg"]:
            cmd = "/sbin/ethtool --offload %s %s off" \
                  % (self.defaultIntf(), off)
            self.cmd(cmd)
        # disable IPv6
        self.cmd("sysctl -w net.ipv6.conf.all.disable_ipv6=1")
        self.cmd("sysctl -w net.ipv6.conf.default.disable_ipv6=1")
        self.cmd("sysctl -w net.ipv6.conf.lo.disable_ipv6=1")
        return r


class ONOSBmv2Switch(Switch):
    """BMv2 software switch with gRPC server"""

    deviceId = 0

    def __init__(self, name, json=None, debugger=False, loglevel="warn",
                 elogger=False, grpcPort=None, cpuPort=255,
                 thriftPort=None, netcfg=True, dryrun=False, pipeconfId="",
                 pktdump=False, valgrind=False, **kwargs):
        Switch.__init__(self, name, **kwargs)
        self.grpcPort = pickUnusedPort() if not grpcPort else grpcPort
        self.thriftPort = pickUnusedPort() if not thriftPort else thriftPort
        if self.dpid:
            self.deviceId = int(self.dpid, 0 if 'x' in self.dpid else 16)
        else:
            self.deviceId = ONOSBmv2Switch.deviceId
            ONOSBmv2Switch.deviceId += 1
        self.cpuPort = cpuPort
        self.json = json
        self.debugger = parseBoolean(debugger)
        self.loglevel = loglevel
        # Important: Mininet removes all /tmp/*.log files in case of exceptions.
        # We want to be able to see the bmv2 log if anything goes wrong, hence
        # avoid the .log extension.
        self.logfile = '/tmp/bmv2-%d-log' % self.deviceId
        self.elogger = parseBoolean(elogger)
        self.pktdump = parseBoolean(pktdump)
        self.netcfg = parseBoolean(netcfg)
        self.dryrun = parseBoolean(dryrun)
        self.valgrind = parseBoolean(valgrind)
        self.netcfgfile = '/tmp/bmv2-%d-netcfg.json' % self.deviceId
        self.pipeconfId = pipeconfId
        self.longitude = kwargs['longitude'] if 'longitude' in kwargs else None
        self.latitude = kwargs['latitude'] if 'latitude' in kwargs else None
        self.onosDeviceId = "device:bmv2:%d" % self.deviceId
        self.logfd = None
        self.bmv2popen = None
        self.stopped = False

        # Remove files from previous executions
        self.cleanupTmpFiles()

        writeToFile("/tmp/bmv2-%d-grpc-port" % self.deviceId, self.grpcPort)
        writeToFile("/tmp/bmv2-%d-thrift-port" % self.deviceId, self.thriftPort)

    def getSourceIp(self, dstIP):
        """
        Queries the Linux routing table to get the source IP that can talk with
        dstIP, and vice versa.
        """
        ipRouteOut = self.cmd('ip route get %s' % dstIP)
        r = re.search(r"src (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})", ipRouteOut)
        return r.group(1) if r else None

    def getDeviceConfig(self, srcIP):
        portData = {}
        portId = 1
        for intfName in self.intfNames():
            if intfName == 'lo':
                continue
            portData[str(portId)] = {
                "number": portId,
                "name": intfName,
                "enabled": True,
                "removed": False,
                "type": "copper",
                "speed": 10000
            }
            portId += 1

        basicCfg = {
            "driver": "bmv2"
        }

        if self.longitude and self.latitude:
            basicCfg["longitude"] = self.longitude
            basicCfg["latitude"] = self.latitude

        cfgData = {
            "generalprovider": {
                "p4runtime": {
                    "ip": srcIP,
                    "port": self.grpcPort,
                    "deviceId": self.deviceId,
                    "deviceKeyId": "p4runtime:%s" % self.onosDeviceId
                }
            },
            "piPipeconf": {
                "piPipeconfId": self.pipeconfId
            },
            "basic": basicCfg,
            "ports": portData
        }

        return cfgData

    def doOnosNetcfg(self, controllerIP):
        """
        Notifies ONOS about the new device via Netcfg.
        """
        srcIP = self.getSourceIp(controllerIP)
        if not srcIP:
            warn("*** WARN: unable to get switch IP address, won't do netcfg\n")
            return

        cfgData = {
            "devices": {
                self.onosDeviceId: self.getDeviceConfig(srcIP)
            }
        }
        with open(self.netcfgfile, 'w') as fp:
            json.dump(cfgData, fp, indent=4)

        if not self.netcfg:
            # Do not push config to ONOS.
            return

        # Build netcfg URL
        url = 'http://%s:8181/onos/v1/network/configuration/' % controllerIP
        # Instantiate password manager for HTTP auth
        pm = urllib2.HTTPPasswordMgrWithDefaultRealm()
        pm.add_password(None, url,
                        os.environ['ONOS_WEB_USER'],
                        os.environ['ONOS_WEB_PASS'])
        urllib2.install_opener(urllib2.build_opener(
            urllib2.HTTPBasicAuthHandler(pm)))
        # Push config data to controller
        req = urllib2.Request(url, json.dumps(cfgData),
                              {'Content-Type': 'application/json'})
        try:
            f = urllib2.urlopen(req)
            print f.read()
            f.close()
        except urllib2.URLError as e:
            warn("*** WARN: unable to push config to ONOS (%s)\n" % e.reason)

    def start(self, controllers):
        bmv2Args = [SIMPLE_SWITCH_GRPC] + self.grpcTargetArgs()
        if self.valgrind:
            bmv2Args = VALGRIND_PREFIX.split() + bmv2Args

        cmdString = " ".join(bmv2Args)

        if self.dryrun:
            info("\n*** DRY RUN (not executing bmv2)")

        info("\nStarting BMv2 target: %s\n" % cmdString)

        try:
            if not self.dryrun:
                # Start the switch
                self.logfd = open(self.logfile, "w")
                self.bmv2popen = self.popen(cmdString,
                                            stdout=self.logfd,
                                            stderr=self.logfd)
                self.waitBmv2Start()
                # We want to be notified if BMv2 dies...
                threading.Thread(target=watchDog, args=[self]).start()

            self.doOnosNetcfg(self.controllerIp(controllers))
        except Exception as ex:
            self.killBmv2()
            self.printBmv2Log()
            raise ex

    def grpcTargetArgs(self):
        args = ['--device-id %s' % str(self.deviceId)]
        for port, intf in self.intfs.items():
            if not intf.IP():
                args.append('-i %d@%s' % (port, intf.name))
        if self.elogger:
            nanomsg = 'ipc:///tmp/bmv2-%d-log.ipc' % self.deviceId
            args.append('--nanolog %s' % nanomsg)
        if self.debugger:
            args.append('--debugger')
        args.append('--log-console')
        if self.pktdump:
            args.append('--pcap --dump-packet-data %s' % PKT_BYTES_TO_DUMP)
        args.append('-L%s' % self.loglevel)
        args.append('--thrift-port %s' % self.thriftPort)
        if not self.json:
            args.append('--no-p4')
        else:
            args.append(self.json)
        # gRPC target-specific options
        args.append('--')
        args.append('--cpu-port %s' % self.cpuPort)
        args.append('--grpc-server-addr 0.0.0.0:%s' % self.grpcPort)
        return args

    def waitBmv2Start(self):
        # Wait for switch to open gRPC port, before sending ONOS the netcfg.
        # Include time-out just in case something hangs.
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        endtime = time.time() + SWITCH_START_TIMEOUT
        while True:
            result = sock.connect_ex(('127.0.0.1', self.grpcPort))
            if result == 0:
                # The port is open. Let's go! (Close socket first)
                sock.close()
                break
            # Port is not open yet. If there is time, we wait a bit.
            if endtime > time.time():
                time.sleep(0.2)
            else:
                # Time's up.
                raise Exception("Switch did not start before timeout")

    def printBmv2Log(self):
        if os.path.isfile(self.logfile):
            print "-" * 80
            print "BMv2 %d log (from %s):" % (self.deviceId, self.logfile)
            with open(self.logfile, 'r') as f:
                lines = f.readlines()
                if len(lines) > BMV2_LOG_LINES:
                    print "..."
                for line in lines[-BMV2_LOG_LINES:]:
                    print line.rstrip()

    @staticmethod
    def controllerIp(controllers):
        try:
            # onos.py
            clist = controllers[0].nodes()
        except AttributeError:
            clist = controllers
        assert len(clist) > 0
        return clist[0].IP()

    def killBmv2(self, log=False):
        if self.bmv2popen is not None:
            self.bmv2popen.kill()
        if self.logfd is not None:
            if log:
                self.logfd.write("*** PROCESS TERMINATED BY MININET ***\n")
            self.logfd.close()

    def cleanupTmpFiles(self):
        self.cmd("rm -f /tmp/bmv2-%d-*" % self.deviceId)

    def stop(self, deleteIntfs=True):
        """Terminate switch."""
        self.stopped = True
        self.killBmv2(log=True)
        Switch.stop(self, deleteIntfs)


# Exports for bin/mn
switches = {'onosbmv2': ONOSBmv2Switch}
hosts = {'onoshost': ONOSHost}
