"""
OpenFlow Test Framework

DataPlane and DataPlanePort classes

Provide the interface to the control the set of ports being used
to stimulate the switch under test.

See the class dataplaneport for more details.  This class wraps
a set of those objects allowing general calls and parsing
configuration.

@todo Add "filters" for matching packets.  Actions supported
for filters should include a callback or a counter
"""

import sys
import os
import socket
import time
import netutils
from threading import Thread
from threading import Lock
from threading import Condition
import select
import logging
from oft_assert import oft_assert
from ofutils import *

have_pypcap = False
try:
    import pcap
    if hasattr(pcap, "pcap"):
        # the incompatible pylibpcap library masquerades as pcap
        have_pypcap = True
except:
    pass

##@todo Find a better home for these identifiers (dataplane)
RCV_SIZE_DEFAULT = 4096
ETH_P_ALL = 0x03
RCV_TIMEOUT = 10000

def match_exp_pkt(exp_pkt, pkt):
    """
    Compare the string value of pkt with the string value of exp_pkt,
    and return True iff they are identical.  If the length of exp_pkt is
    less than the minimum Ethernet frame size (60 bytes), then padding
    bytes in pkt are ignored.
    """
    e = str(exp_pkt)
    p = str(pkt)
    if len(e) < 60:
        p = p[:len(e)]
    return e == p


class DataPlanePort(Thread):
    """
    Class defining a port monitoring object.

    Control a dataplane port connected to the switch under test.
    Creates a promiscuous socket on a physical interface.
    Queues the packets received on that interface with time stamps.
    Inherits from Thread class as meant to run in background.  Also
    supports polling.

    Currently assumes a controlling 'parent' which maintains a
    common Lock object and a total packet-pending count.  May want
    to decouple that some day.
    """

    def __init__(self, interface_name, port_number, parent, max_pkts=1024):
        """
        Set up a port monitor object
        @param interface_name The name of the physical interface like eth1
        @param port_number The port number associated with this port
        @param parent The controlling dataplane object; for pkt wait CV
        @param max_pkts Maximum number of pkts to keep in queue
        """
        Thread.__init__(self)
        self.interface_name = interface_name
        self.max_pkts = max_pkts
        self.packets_total = 0
        self.packets = []
        self.packets_discarded = 0
        self.port_number = port_number
        logname = "dp-" + interface_name
        self.logger = logging.getLogger(logname)
        try:
            self.socket = self.interface_open(interface_name)
        except:
            self.logger.info("Could not open socket")
            raise
        self.logger.info("Opened port monitor (class %s)", type(self).__name__)
        self.parent = parent
        self.killed = False

        # Used to wake up the event loop in kill()
        self.waker = EventDescriptor()

    def interface_open(self, interface_name):
        """
        Open a socket in a promiscuous mode for a data connection.
        @param interface_name port name as a string such as 'eth1'
        @retval s socket
        """
        s = socket.socket(socket.AF_PACKET, socket.SOCK_RAW,
                          socket.htons(ETH_P_ALL))
        s.bind((interface_name, 0))
        netutils.set_promisc(s, interface_name)
        s.settimeout(RCV_TIMEOUT)
        return s

    def run(self):
        """
        Activity function for class
        """
        self.socs = [self.socket, self.waker]
        error_warned = False # Have we warned about error?
        while not self.killed:
            try:
                sel_in, sel_out, sel_err = \
                    select.select(self.socs, [], [], 1)
            except:
                print sys.exc_info()
                self.logger.error("Select error, exiting")
                break

            if (sel_in is None) or (len(sel_in) == 0):
                continue

            if self.waker in sel_in:
                self.waker.wait()
                continue

            try:
                rcvmsg = self.socket.recv(RCV_SIZE_DEFAULT)
            except socket.error:
                if not error_warned:
                    self.logger.info("Socket error on recv")
                    error_warned = True
                continue

            if len(rcvmsg) == 0:
                self.logger.info("Zero len pkt rcvd")
                self.kill()
                break

            rcvtime = time.time()
            self.logger.debug("Pkt len " + str(len(rcvmsg)) +
                     " in at " + str(rcvtime) + " on port " +
                     str(self.port_number))

            # Enqueue packet
            with self.parent.pkt_sync:
                if len(self.packets) >= self.max_pkts:
                    # Queue full, throw away oldest
                    self.packets.pop(0)
                    self.packets_discarded += 1
                    self.logger.debug("Discarding oldest packet to make room")
                self.packets.append((rcvmsg, rcvtime))
                self.packets_total += 1
                self.parent.pkt_sync.notify_all()

        self.logger.info("Thread exit")

    def kill(self):
        """
        Terminate the running thread
        """
        self.logger.debug("Port monitor kill")
        self.killed = True
        self.waker.notify()
        try:
            self.socket.close()
        except:
            self.logger.info("Ignoring dataplane soc shutdown error")

    def timestamp_head(self):
        """
        Return the timestamp of the head of queue or None if empty
        """
        rv = None
        try:
            rv = self.packets[0][1]
        except:
            rv = None
        return rv

    def flush(self):
        """
        Clear the packet queue
        """
        with self.parent.pkt_sync:
            self.packets_discarded += len(self.packets)
            self.packets = []

    def send(self, packet):
        """
        Send a packet to the dataplane port
        @param packet The packet data to send to the port
        @retval The number of bytes sent
        """
        return self.socket.send(packet)

    def register(self, handler):
        """
        Register a callback function to receive packets from this
        port.  The callback will be passed the packet, the
        interface name and the port number (if set) on which the
        packet was received.

        To be implemented
        """
        pass

    def show(self, prefix=''):

        print prefix + "Name:          " + self.interface_name
        print prefix + "Pkts pending:  " + str(len(self.packets))
        print prefix + "Pkts total:    " + str(self.packets_total)
        print prefix + "socket:        " + str(self.socket)

    
    def port_down(self,port_number,config):

        """
        Grabs a port from the dataplane ports and brings it down by 
        shutting the corresponding interface 
        @port_number The port number which has brought to be down
        @interface_name The interface corresponding to the port that needs to
        be brought down

        """
        interface_name = config["port_map"].get(port_number)
        cmd = 'ifdown '+ interface_name
        os.system(cmd)

    def port_up(self,port_number,config):

        """
        Grabs a port from the dataplane ports and brings it up by 
        starting up the corresponding interface 
        @port_number The port number which has to brought up
        @interface_name The interface corresponding to the port that has to
        be brought up

        """
        interface_name = config["port_map"].get(port_number)
        cmd = 'ifup '+ interface_name
        os.system(cmd)


class DataPlanePortPcap(DataPlanePort):
    """
    Alternate port implementation using libpcap. This is required for recent
    versions of Linux (such as Linux 3.2 included in Ubuntu 12.04) which
    offload the VLAN tag, so it isn't in the data returned from a read on a raw
    socket. libpcap understands how to read the VLAN tag from the kernel.
    """

    def __init__(self, interface_name, port_number, parent, max_pkts=1024):
        DataPlanePort.__init__(self, interface_name, port_number, parent, max_pkts)

    def interface_open(self, interface_name):
        """
        Open a PCAP interface.
        """
        self.pcap = pcap.pcap(interface_name)
        self.pcap.setnonblock()
        return self.pcap.fileno()

    def run(self):
        """
        Activity function for class
        """
        while not self.killed:
            try:
                sel_in, sel_out, sel_err = select.select([self.socket, self.waker], [], [], 1)
            except:
                print sys.exc_info()
                self.logger.error("Select error, exiting")
                break

            if (sel_in is None) or (len(sel_in) == 0):
                continue

            if self.waker in sel_in:
                self.waker.wait()
                continue

            # Enqueue packet
            with self.parent.pkt_sync:
                for (timestamp, rcvmsg) in self.pcap.readpkts():
                    self.logger.debug("Pkt len " + str(len(rcvmsg)) +
                                      " in at " + str(timestamp) + " on port " +
                                      str(self.port_number))

                    if len(self.packets) >= self.max_pkts:
                        # Queue full, throw away oldest
                        self.packets.pop(0)
                        self.packets_discarded += 1
                        self.logger.debug("Discarding oldest packet to make room")
                    self.packets.append((rcvmsg, timestamp))
                    self.packets_total += 1
                self.parent.pkt_sync.notify_all()

        self.logger.info("Thread exit")

    def kill(self):
        """
        Terminate the running thread
        """
        self.logger.debug("Port monitor kill")
        self.killed = True
        self.waker.notify()
        # pcap object is closed on GC.

    def send(self, packet):
        """
        Send a packet to the dataplane port
        @param packet The packet data to send to the port
        @retval The number of bytes sent
        """
        return self.pcap.inject(packet, len(packet))

class DataPlane:
    """
    Class defining access primitives to the data plane
    Controls a list of DataPlanePort objects
    """
    def __init__(self, config=None):
        self.port_list = {}
        # pkt_sync serves double duty as a regular top level lock and
        # as a condition variable
        self.pkt_sync = Condition()

        self.logger = logging.getLogger("dataplane")

        if config is None:
            self.config = {}
        else:
            self.config = config; 

        ############################################################
        #
        # The platform/config can provide a custom DataPlanePort class
        # here if you have a custom implementation with different
        # behavior. 
        #
        # Set config.dataplane.portclass = MyDataPlanePortClass
        # where MyDataPlanePortClass has the same interface as the class
        # DataPlanePort defined here. 
        #
        if "dataplane" in self.config and "portclass" in self.config["dataplane"]:
            self.dppclass = self.config["dataplane"]["portclass"]
        elif have_pypcap:
            self.dppclass = DataPlanePortPcap
        else:
            self.logger.warning("Missing pypcap, VLAN tests may fail. See README for installation instructions.")
            self.dppclass = DataPlanePort

    def port_add(self, interface_name, port_number):
        """
        Add a port to the dataplane
        TBD:  Max packets for queue?
        @param interface_name The name of the physical interface like eth1
        @param port_number The port number used to refer to the port
        """

        self.port_list[port_number] = self.dppclass(interface_name, 
                                                    port_number, self); 

        self.port_list[port_number].start()

    def send(self, port_number, packet):
        """
        Send a packet to the given port
        @param port_number The port to send the data to
        @param packet Raw packet data to send to port
        """
        self.logger.debug("Sending %d bytes to port %d" %
                          (len(packet), port_number))
        bytes = self.port_list[port_number].send(packet)
        if bytes != len(packet):
            self.logger.error("Unhandled send error, length mismatch %d != %d" %
                     (bytes, len(packet)))
        return bytes

    # Returns the port with the oldest packet, or None if no packets are queued.
    def oldest_port(self):
        min_port = None
        min_time = float('inf')
        for port in self.port_list.values():
            ptime = port.timestamp_head()
            if ptime and ptime < min_time:
                min_time = ptime
                min_port = port
        return min_port

    # Dequeues and yields packets in the order they were received.
    # Yields (port, packet, received time).
    # If port_number is not specified yields packets from all ports.
    def packets(self, port_number=None):
        while True:
            if port_number == None:
                port = self.oldest_port()
            else:
                port = self.port_list[port_number]

            if port == None or len(port.packets) == 0:
                self.logger.debug("Out of packets for port %s" % str(port_number))
                # Out of packets
                break

            pkt, time = port.packets.pop(0)
            yield (port, pkt, time)

    def poll(self, port_number=None, timeout=-1, exp_pkt=None):
        """
        Poll one or all dataplane ports for a packet

        If port_number is given, get the oldest packet from that port.
        Otherwise, find the port with the oldest packet and return
        that packet.

        If exp_pkt is true, discard all packets until that one is found

        @param port_number If set, get packet from this port
        @param timeout If positive and no packet is available, block
        until a packet is received or for this many seconds
        @param exp_pkt If not None, look for this packet and ignore any
        others received.  Note that if port_number is None, all packets
        from all ports will be discarded until the exp_pkt is found
        @return The triple port_number, packet, pkt_time where packet
        is received from port_number at time pkt_time.  If a timeout
        occurs, return None, None, None
        """

        if exp_pkt and not port_number:
            self.logger.warn("Dataplane poll with exp_pkt but no port number")

        # Retrieve the packet. Returns (port number, packet, time).
        def grab():
            self.logger.debug("Grabbing packet")
            for (port, pkt, time) in self.packets(port_number):
                self.logger.debug("Checking packet from port %d" % port.port_number)
                if not exp_pkt or match_exp_pkt(exp_pkt, pkt):
                    return (port, pkt, time)
            self.logger.debug("Did not find packet")
            return None

        with self.pkt_sync:
            ret = timed_wait(self.pkt_sync, grab, timeout=timeout)

        if ret != None:
            (port, pkt, time) = ret
            return (port.port_number, pkt, time)
        else:
            self.logger.debug("Poll time out, no packet from " + str(port_number))
            return (None, None, None)

    def kill(self, join_threads=True):
        """
        Close all sockets for dataplane
        @param join_threads If True call join on each thread
        """
        for port_number in self.port_list.keys():
            self.port_list[port_number].kill()

        if join_threads:
            for port_number in self.port_list.keys():
                self.logger.debug("Joining " + str(port_number))
                self.port_list[port_number].join()

        self.port_list = None

        self.logger.info("DataPlane shutdown")

    def show(self, prefix=''):
        print prefix + "Dataplane Controller"
        for pnum, port in self.port_list.items():
            print prefix + "OpenFlow Port Number " + str(pnum)
            port.show(prefix + '  ')

    def port_down(self,port_number):
        """Brings the specified port down"""
        self.port_list[port_number].port_down(port_number,self.config)

    def port_up(self,port_number):
        """Brings the specified port up"""
        self.port_list[port_number].port_up(port_number,self.config)
