import sys
import copy
import logging
import types
import time
import re

try:
    import scapy.all as scapy
except:
    try:
        import scapy as scapy
    except:
        sys.exit("Need to install scapy for packet parsing")

import oftest
import oftest.controller
import oftest.dataplane
import oftest.parse
import ofp

global skipped_test_count
skipped_test_count = 0

_import_blacklist = set(locals().keys())

# Some useful defines
IP_ETHERTYPE = 0x800
TCP_PROTOCOL = 0x6
UDP_PROTOCOL = 0x11

MINSIZE = 0

def delete_all_flows(ctrl):
    """
    Delete all flows on the switch
    @param ctrl The controller object for the test
    """

    logging.info("Deleting all flows")
    msg = ofp.message.flow_delete()
    msg.match.wildcards = ofp.OFPFW_ALL
    msg.out_port = ofp.OFPP_NONE
    msg.buffer_id = 0xffffffff
    ctrl.message_send(msg)
    return 0 # for backwards compatibility

def required_wildcards(parent):
    w = test_param_get('required_wildcards', default='default')
    if w == 'l3-l4':
        return (ofp.OFPFW_NW_SRC_ALL | ofp.OFPFW_NW_DST_ALL | ofp.OFPFW_NW_TOS
                | ofp.OFPFW_NW_PROTO | ofp.OFPFW_TP_SRC | ofp.OFPFW_TP_DST)
    else:
        return 0

def simple_tcp_packet(pktlen=100, 
                      eth_dst='00:01:02:03:04:05',
                      eth_src='00:06:07:08:09:0a',
                      dl_vlan_enable=False,
                      vlan_vid=0,
                      vlan_pcp=0,
                      dl_vlan_cfi=0,
                      ip_src='192.168.0.1',
                      ip_dst='192.168.0.2',
                      ip_tos=0,
                      ip_ttl=64,
                      tcp_sport=1234,
                      tcp_dport=80,
                      ip_ihl=None,
                      ip_options=False
                      ):
    """
    Return a simple dataplane TCP packet

    Supports a few parameters:
    @param len Length of packet in bytes w/o CRC
    @param eth_dst Destinatino MAC
    @param eth_src Source MAC
    @param dl_vlan_enable True if the packet is with vlan, False otherwise
    @param vlan_vid VLAN ID
    @param vlan_pcp VLAN priority
    @param ip_src IP source
    @param ip_dst IP destination
    @param ip_tos IP ToS
    @param ip_ttl IP TTL
    @param tcp_dport TCP destination port
    @param ip_sport TCP source port

    Generates a simple TCP request.  Users
    shouldn't assume anything about this packet other than that
    it is a valid ethernet/IP/TCP frame.
    """

    if MINSIZE > pktlen:
        pktlen = MINSIZE

    # Note Dot1Q.id is really CFI
    if (dl_vlan_enable):
        pkt = scapy.Ether(dst=eth_dst, src=eth_src)/ \
            scapy.Dot1Q(prio=vlan_pcp, id=dl_vlan_cfi, vlan=vlan_vid)/ \
            scapy.IP(src=ip_src, dst=ip_dst, tos=ip_tos, ttl=ip_ttl, ihl=ip_ihl)/ \
            scapy.TCP(sport=tcp_sport, dport=tcp_dport)
    else:
        if not ip_options:
            pkt = scapy.Ether(dst=eth_dst, src=eth_src)/ \
                scapy.IP(src=ip_src, dst=ip_dst, tos=ip_tos, ttl=ip_ttl, ihl=ip_ihl)/ \
                scapy.TCP(sport=tcp_sport, dport=tcp_dport)
        else:
            pkt = scapy.Ether(dst=eth_dst, src=eth_src)/ \
                scapy.IP(src=ip_src, dst=ip_dst, tos=ip_tos, ttl=ip_ttl, ihl=ip_ihl, options=ip_options)/ \
                scapy.TCP(sport=tcp_sport, dport=tcp_dport)

    pkt = pkt/("D" * (pktlen - len(pkt)))

    return pkt

def simple_udp_packet(pktlen=100,
                      eth_dst='00:01:02:03:04:05',
                      eth_src='00:06:07:08:09:0a',
                      dl_vlan_enable=False,
                      vlan_vid=0,
                      vlan_pcp=0,
                      dl_vlan_cfi=0,
                      ip_src='192.168.0.1',
                      ip_dst='192.168.0.2',
                      ip_tos=0,
                      ip_ttl=64,
                      udp_sport=1234,
                      udp_dport=80,
                      ip_ihl=None,
                      ip_options=False
                      ):
    """
    Return a simple dataplane UDP packet

    Supports a few parameters:
    @param len Length of packet in bytes w/o CRC
    @param eth_dst Destination MAC
    @param eth_src Source MAC
    @param dl_vlan_enable True if the packet is with vlan, False otherwise
    @param vlan_vid VLAN ID
    @param vlan_pcp VLAN priority
    @param ip_src IP source
    @param ip_dst IP destination
    @param ip_tos IP ToS
    @param ip_ttl IP TTL
    @param udp_dport UDP destination port
    @param udp_sport UDP source port

    Generates a simple UDP packet. Users shouldn't assume anything about
    this packet other than that it is a valid ethernet/IP/UDP frame.
    """

    if MINSIZE > pktlen:
        pktlen = MINSIZE

    # Note Dot1Q.id is really CFI
    if (dl_vlan_enable):
        pkt = scapy.Ether(dst=eth_dst, src=eth_src)/ \
            scapy.Dot1Q(prio=vlan_pcp, id=dl_vlan_cfi, vlan=vlan_vid)/ \
            scapy.IP(src=ip_src, dst=ip_dst, tos=ip_tos, ttl=ip_ttl, ihl=ip_ihl)/ \
            scapy.UDP(sport=udp_sport, dport=udp_dport)
    else:
        if not ip_options:
            pkt = scapy.Ether(dst=eth_dst, src=eth_src)/ \
                scapy.IP(src=ip_src, dst=ip_dst, tos=ip_tos, ttl=ip_ttl, ihl=ip_ihl)/ \
                scapy.UDP(sport=udp_sport, dport=udp_dport)
        else:
            pkt = scapy.Ether(dst=eth_dst, src=eth_src)/ \
                scapy.IP(src=ip_src, dst=ip_dst, tos=ip_tos, ttl=ip_ttl, ihl=ip_ihl, options=ip_options)/ \
                scapy.UDP(sport=udp_sport, dport=udp_dport)

    pkt = pkt/("D" * (pktlen - len(pkt)))

    return pkt

def simple_icmp_packet(pktlen=60, 
                      eth_dst='00:01:02:03:04:05',
                      eth_src='00:06:07:08:09:0a',
                      dl_vlan_enable=False,
                      vlan_vid=0,
                      vlan_pcp=0,
                      ip_src='192.168.0.1',
                      ip_dst='192.168.0.2',
                      ip_tos=0,
                      ip_ttl=64,
                      icmp_type=8,
                      icmp_code=0
                      ):
    """
    Return a simple ICMP packet

    Supports a few parameters:
    @param len Length of packet in bytes w/o CRC
    @param eth_dst Destinatino MAC
    @param eth_src Source MAC
    @param dl_vlan_enable True if the packet is with vlan, False otherwise
    @param vlan_vid VLAN ID
    @param vlan_pcp VLAN priority
    @param ip_src IP source
    @param ip_dst IP destination
    @param ip_tos IP ToS
    @param ip_ttl IP TTL
    @param icmp_type ICMP type
    @param icmp_code ICMP code

    Generates a simple ICMP ECHO REQUEST.  Users
    shouldn't assume anything about this packet other than that
    it is a valid ethernet/ICMP frame.
    """

    if MINSIZE > pktlen:
        pktlen = MINSIZE

    if (dl_vlan_enable):
        pkt = scapy.Ether(dst=eth_dst, src=eth_src)/ \
            scapy.Dot1Q(prio=vlan_pcp, id=0, vlan=vlan_vid)/ \
            scapy.IP(src=ip_src, dst=ip_dst, ttl=ip_ttl, tos=ip_tos)/ \
            scapy.ICMP(type=icmp_type, code=icmp_code)
    else:
        pkt = scapy.Ether(dst=eth_dst, src=eth_src)/ \
            scapy.IP(src=ip_src, dst=ip_dst, ttl=ip_ttl, tos=ip_tos)/ \
            scapy.ICMP(type=icmp_type, code=icmp_code)

    pkt = pkt/("0" * (pktlen - len(pkt)))

    return pkt

def simple_arp_packet(pktlen=60, 
                      eth_dst='ff:ff:ff:ff:ff:ff',
                      eth_src='00:06:07:08:09:0a',
                      arp_op=1,
                      ip_snd='192.168.0.1',
                      ip_tgt='192.168.0.2',
                      hw_snd='00:06:07:08:09:0a',
                      hw_tgt='00:00:00:00:00:00',
                      ):
    """
    Return a simple ARP packet

    Supports a few parameters:
    @param len Length of packet in bytes w/o CRC
    @param eth_dst Destinatino MAC
    @param eth_src Source MAC
    @param arp_op Operation (1=request, 2=reply)
    @param ip_snd Sender IP
    @param ip_tgt Target IP
    @param hw_snd Sender hardware address
    @param hw_tgt Target hardware address

    Generates a simple ARP REQUEST.  Users
    shouldn't assume anything about this packet other than that
    it is a valid ethernet/ARP frame.
    """

    if MINSIZE > pktlen:
        pktlen = MINSIZE

    pkt = scapy.Ether(dst=eth_dst, src=eth_src)/ \
          scapy.ARP(hwsrc=hw_snd, hwdst=hw_tgt, pdst=ip_tgt, psrc=ip_snd, op=arp_op)

    pkt = pkt/("0" * (pktlen - len(pkt)))

    return pkt

def simple_eth_packet(pktlen=60,
                      eth_dst='00:01:02:03:04:05',
                      eth_src='01:80:c2:00:00:00',
                      eth_type=0x88cc):

    if MINSIZE > pktlen:
        pktlen = MINSIZE

    pkt = scapy.Ether(dst=eth_dst, src=eth_src, type=eth_type)

    pkt = pkt/("0" * (pktlen - len(pkt)))

    return pkt

def qinq_tcp_packet(pktlen=100, 
                    eth_dst='00:01:02:03:04:05',
                    eth_src='00:06:07:08:09:0a',
                    dl_vlan_outer=20,
                    dl_vlan_pcp_outer=0,
                    dl_vlan_cfi_outer=0,
                    vlan_vid=10,
                    vlan_pcp=0,
                    dl_vlan_cfi=0,
                    ip_src='192.168.0.1',
                    ip_dst='192.168.0.2',
                    ip_tos=0,
                    ip_ttl=64,
                    tcp_sport=1234,
                    tcp_dport=80,
                    ip_ihl=None,
                    ip_options=False
                    ):
    """
    Return a doubly tagged dataplane TCP packet

    Supports a few parameters:
    @param len Length of packet in bytes w/o CRC
    @param eth_dst Destinatino MAC
    @param eth_src Source MAC
    @param dl_vlan_outer Outer VLAN ID
    @param dl_vlan_pcp_outer Outer VLAN priority
    @param dl_vlan_cfi_outer Outer VLAN cfi bit
    @param vlan_vid Inner VLAN ID
    @param vlan_pcp VLAN priority
    @param dl_vlan_cfi VLAN cfi bit
    @param ip_src IP source
    @param ip_dst IP destination
    @param ip_tos IP ToS
    @param tcp_dport TCP destination port
    @param ip_sport TCP source port

    Generates a TCP request.  Users
    shouldn't assume anything about this packet other than that
    it is a valid ethernet/IP/TCP frame.
    """

    if MINSIZE > pktlen:
        pktlen = MINSIZE

    # Note Dot1Q.id is really CFI
    pkt = scapy.Ether(dst=eth_dst, src=eth_src)/ \
          scapy.Dot1Q(prio=dl_vlan_pcp_outer, id=dl_vlan_cfi_outer, vlan=dl_vlan_outer)/ \
          scapy.Dot1Q(prio=vlan_pcp, id=dl_vlan_cfi, vlan=vlan_vid)/ \
          scapy.IP(src=ip_src, dst=ip_dst, tos=ip_tos, ttl=ip_ttl, ihl=ip_ihl)/ \
          scapy.TCP(sport=tcp_sport, dport=tcp_dport)

    pkt = pkt/("D" * (pktlen - len(pkt)))

    return pkt

def do_barrier(ctrl, timeout=-1):
    """
    Do a barrier command
    Return 0 on success, -1 on error
    """
    b = ofp.message.barrier_request()
    (resp, pkt) = ctrl.transact(b, timeout=timeout)
    if resp is None:
        raise AssertionError("barrier failed")
    # We'll trust the transaction processing in the controller that xid matched
    return 0 # for backwards compatibility

def port_config_get(controller, port_no):
    """
    Get a port's configuration

    Gets the switch feature configuration and grabs one port's
    configuration

    @returns (hwaddr, config, advert) The hwaddress, configuration and
    advertised values
    """
    request = ofp.message.features_request()
    reply, pkt = controller.transact(request)
    logging.debug(reply.show())
    if reply is None:
        logging.warn("Get feature request failed")
        return None, None, None
    for idx in range(len(reply.ports)):
        if reply.ports[idx].port_no == port_no:
            return (reply.ports[idx].hw_addr, reply.ports[idx].config,
                    reply.ports[idx].advertised)
    
    logging.warn("Did not find port number for port config")
    return None, None, None

def port_config_set(controller, port_no, config, mask):
    """
    Set the port configuration according the given parameters

    Gets the switch feature configuration and updates one port's
    configuration value according to config and mask
    """
    logging.info("Setting port " + str(port_no) + " to config " + str(config))
    request = ofp.message.features_request()
    reply, pkt = controller.transact(request)
    if reply is None:
        return -1
    logging.debug(reply.show())
    p = None
    for idx in range(len(reply.ports)):
        if reply.ports[idx].port_no == port_no:
            p = reply.ports[idx]
            break
    mod = ofp.message.port_mod()
    mod.port_no = port_no
    if p:
        mod.hw_addr = p.hw_addr
    mod.config = config
    mod.mask = mask
    if p:
        mod.advertise = p.advertised
    controller.message_send(mod)
    return 0

def receive_pkt_check(dp, pkt, yes_ports, no_ports, assert_if):
    """
    Check for proper receive packets across all ports
    @param dp The dataplane object
    @param pkt Expected packet; may be None if yes_ports is empty
    @param yes_ports Set or list of ports that should recieve packet
    @param no_ports Set or list of ports that should not receive packet
    @param assert_if Object that implements assertXXX
    """

    # Wait this long for packets that we don't expect to receive.
    # 100ms is (rarely) too short for positive tests on slow
    # switches but is definitely not too short for a negative test.
    negative_timeout = 0.1

    exp_pkt_arg = None
    if oftest.config["relax"]:
        exp_pkt_arg = pkt

    for ofport in yes_ports:
        logging.debug("Checking for pkt on port " + str(ofport))
        (rcv_port, rcv_pkt, pkt_time) = dp.poll(
            port_number=ofport, exp_pkt=exp_pkt_arg)
        assert_if.assertTrue(rcv_pkt is not None, 
                             "Did not receive pkt on " + str(ofport))
        if not oftest.dataplane.match_exp_pkt(pkt, rcv_pkt):
            logging.debug("Expected %s" % format_packet(pkt))
            logging.debug("Received %s" % format_packet(rcv_pkt))
        assert_if.assertTrue(oftest.dataplane.match_exp_pkt(pkt, rcv_pkt),
                             "Received packet does not match expected packet " +
                             "on port " + str(ofport))
    if len(no_ports) > 0:
        time.sleep(negative_timeout)
    for ofport in no_ports:
        logging.debug("Negative check for pkt on port " + str(ofport))
        (rcv_port, rcv_pkt, pkt_time) = dp.poll(
            port_number=ofport, timeout=0, exp_pkt=exp_pkt_arg)
        assert_if.assertTrue(rcv_pkt is None, 
                             "Unexpected pkt on port " + str(ofport))


def receive_pkt_verify(parent, egr_ports, exp_pkt, ing_port):
    """
    Receive a packet and verify it matches an expected value
    @param egr_port A single port or list of ports

    parent must implement dataplane, assertTrue and assertEqual
    """
    exp_pkt_arg = None
    if oftest.config["relax"]:
        exp_pkt_arg = exp_pkt

    if type(egr_ports) == type([]):
        egr_port_list = egr_ports
    else:
        egr_port_list = [egr_ports]

    # Expect a packet from each port on egr port list
    for egr_port in egr_port_list:
        check_port = egr_port
        if egr_port == ofp.OFPP_IN_PORT:
            check_port = ing_port
        (rcv_port, rcv_pkt, pkt_time) = parent.dataplane.poll(
            port_number=check_port, exp_pkt=exp_pkt_arg)

        if rcv_pkt is None:
            logging.error("ERROR: No packet received from " + 
                                str(check_port))

        parent.assertTrue(rcv_pkt is not None,
                          "Did not receive packet port " + str(check_port))
        logging.debug("Packet len " + str(len(rcv_pkt)) + " in on " + 
                            str(rcv_port))

        if str(exp_pkt) != str(rcv_pkt):
            logging.error("ERROR: Packet match failed.")
            logging.debug("Expected len " + str(len(exp_pkt)) + ": "
                                + str(exp_pkt).encode('hex'))
            logging.debug("Received len " + str(len(rcv_pkt)) + ": "
                                + str(rcv_pkt).encode('hex'))
            logging.debug("Expected packet: " + inspect_packet(scapy.Ether(str(exp_pkt))))
            logging.debug("Received packet: " + inspect_packet(scapy.Ether(str(rcv_pkt))))
        parent.assertEqual(str(exp_pkt), str(rcv_pkt),
                           "Packet match error on port " + str(check_port))

def match_verify(parent, req_match, res_match):
    """
    Verify flow matches agree; if they disagree, report where

    parent must implement assertEqual
    Use str() to ensure content is compared and not pointers
    """

    parent.assertEqual(req_match.wildcards, res_match.wildcards,
                       'Match failed: wildcards: ' + hex(req_match.wildcards) +
                       " != " + hex(res_match.wildcards))
    parent.assertEqual(req_match.in_port, res_match.in_port,
                       'Match failed: in_port: ' + str(req_match.in_port) +
                       " != " + str(res_match.in_port))
    parent.assertEqual(str(req_match.eth_src), str(res_match.eth_src),
                       'Match failed: eth_src: ' + str(req_match.eth_src) +
                       " != " + str(res_match.eth_src))
    parent.assertEqual(str(req_match.eth_dst), str(res_match.eth_dst),
                       'Match failed: eth_dst: ' + str(req_match.eth_dst) +
                       " != " + str(res_match.eth_dst))
    parent.assertEqual(req_match.vlan_vid, res_match.vlan_vid,
                       'Match failed: vlan_vid: ' + str(req_match.vlan_vid) +
                       " != " + str(res_match.vlan_vid))
    parent.assertEqual(req_match.vlan_pcp, res_match.vlan_pcp,
                       'Match failed: vlan_pcp: ' + 
                       str(req_match.vlan_pcp) + " != " + 
                       str(res_match.vlan_pcp))
    parent.assertEqual(req_match.eth_type, res_match.eth_type,
                       'Match failed: eth_type: ' + str(req_match.eth_type) +
                       " != " + str(res_match.eth_type))

    if (not(req_match.wildcards & ofp.OFPFW_DL_TYPE)
        and (req_match.eth_type == IP_ETHERTYPE)):
        parent.assertEqual(req_match.ip_dscp, res_match.ip_dscp,
                           'Match failed: ip_dscp: ' + str(req_match.ip_dscp) +
                           " != " + str(res_match.ip_dscp))
        parent.assertEqual(req_match.ip_proto, res_match.ip_proto,
                           'Match failed: ip_proto: ' + str(req_match.ip_proto) +
                           " != " + str(res_match.ip_proto))
        parent.assertEqual(req_match.ipv4_src, res_match.ipv4_src,
                           'Match failed: ipv4_src: ' + str(req_match.ipv4_src) +
                           " != " + str(res_match.ipv4_src))
        parent.assertEqual(req_match.ipv4_dst, res_match.ipv4_dst,
                           'Match failed: ipv4_dst: ' + str(req_match.ipv4_dst) +
                           " != " + str(res_match.ipv4_dst))

        if (not(req_match.wildcards & ofp.OFPFW_NW_PROTO)
            and ((req_match.ip_proto == TCP_PROTOCOL)
                 or (req_match.ip_proto == UDP_PROTOCOL))):
            parent.assertEqual(req_match.tcp_src, res_match.tcp_src,
                               'Match failed: tcp_src: ' + 
                               str(req_match.tcp_src) +
                               " != " + str(res_match.tcp_src))
            parent.assertEqual(req_match.tcp_dst, res_match.tcp_dst,
                               'Match failed: tcp_dst: ' + 
                               str(req_match.tcp_dst) +
                               " != " + str(res_match.tcp_dst))

def packet_to_flow_match(parent, packet):
    match = oftest.parse.packet_to_flow_match(packet)
    match.wildcards |= required_wildcards(parent)
    return match

def flow_msg_create(parent, pkt, ing_port=None, action_list=None, wildcards=None,
               egr_ports=None, egr_queue=None, check_expire=False, in_band=False):
    """
    Create a flow message

    Match on packet with given wildcards.  
    See flow_match_test for other parameter descriptoins
    @param egr_queue if not None, make the output an enqueue action
    @param in_band if True, do not wildcard ingress port
    @param egr_ports None (drop), single port or list of ports
    """
    match = oftest.parse.packet_to_flow_match(pkt)
    parent.assertTrue(match is not None, "Flow match from pkt failed")
    if wildcards is None:
        wildcards = required_wildcards(parent)
    if in_band:
        wildcards &= ~ofp.OFPFW_IN_PORT
    match.wildcards = wildcards
    match.in_port = ing_port

    if type(egr_ports) == type([]):
        egr_port_list = egr_ports
    else:
        egr_port_list = [egr_ports]

    request = ofp.message.flow_add()
    request.match = match
    request.buffer_id = 0xffffffff
    if check_expire:
        request.flags |= ofp.OFPFF_SEND_FLOW_REM
        request.hard_timeout = 1

    if action_list is not None:
        for act in action_list:
            logging.debug("Adding action " + act.show())
            request.actions.append(act)

    # Set up output/enqueue action if directed
    if egr_queue is not None:
        parent.assertTrue(egr_ports is not None, "Egress port not set")
        act = ofp.action.enqueue()
        for egr_port in egr_port_list:
            act.port = egr_port
            act.queue_id = egr_queue
            request.actions.append(act)
    elif egr_ports is not None:
        for egr_port in egr_port_list:
            act = ofp.action.output()
            act.port = egr_port
            request.actions.append(act)

    logging.debug(request.show())

    return request

def flow_msg_install(parent, request, clear_table_override=None):
    """
    Install a flow mod message in the switch

    @param parent Must implement controller, assertEqual, assertTrue
    @param request The request, all set to go
    @param clear_table If true, clear the flow table before installing
    """

    clear_table = test_param_get('clear_table', default=True)
    if(clear_table_override != None):
        clear_table = clear_table_override

    if clear_table: 
        logging.debug("Clear flow table")
        delete_all_flows(parent.controller)

    logging.debug("Insert flow")
    parent.controller.message_send(request)

    do_barrier(parent.controller)

def flow_match_test_port_pair(parent, ing_port, egr_ports, wildcards=None,
                              vlan_vid=-1, pkt=None, exp_pkt=None,
                              action_list=None):
    """
    Flow match test on single TCP packet
    @param egr_ports A single port or list of ports

    Run test with packet through switch from ing_port to egr_port
    See flow_match_test for parameter descriptions
    """

    if wildcards is None:
        wildcards = required_wildcards(parent)
    logging.info("Pkt match test: " + str(ing_port) + " to " + 
                       str(egr_ports))
    logging.debug("  WC: " + hex(wildcards) + " vlan: " + str(vlan_vid))
    if pkt is None:
        pkt = simple_tcp_packet(dl_vlan_enable=(vlan_vid >= 0), vlan_vid=vlan_vid)

    request = flow_msg_create(parent, pkt, ing_port=ing_port, 
                              wildcards=wildcards, egr_ports=egr_ports,
                              action_list=action_list)

    flow_msg_install(parent, request)

    logging.debug("Send packet: " + str(ing_port) + " to " + 
                        str(egr_ports))
    parent.dataplane.send(ing_port, str(pkt))

    if exp_pkt is None:
        exp_pkt = pkt
    receive_pkt_verify(parent, egr_ports, exp_pkt, ing_port)

def flow_match_test_pktout(parent, ing_port, egr_ports,
                           vlan_vid=-1, pkt=None, exp_pkt=None,
                           action_list=None):
    """
    Packet-out test on single TCP packet
    @param egr_ports A single port or list of ports

    Run test sending packet-out to egr_ports. The goal is to test the actions
    taken on the packet, not the matching which is of course irrelevant.
    See flow_match_test for parameter descriptions
    """

    if pkt is None:
        pkt = simple_tcp_packet(dl_vlan_enable=(vlan_vid >= 0), vlan_vid=vlan_vid)

    msg = ofp.message.packet_out()
    msg.in_port = ing_port
    msg.data = str(pkt)
    if action_list is not None:
        for act in action_list:
            msg.actions.append(act)

    # Set up output action
    if egr_ports is not None:
        for egr_port in egr_ports:
            act = ofp.action.output()
            act.port = egr_port
            msg.actions.append(act)

    logging.debug(msg.show())
    parent.controller.message_send(msg)

    if exp_pkt is None:
        exp_pkt = pkt
    receive_pkt_verify(parent, egr_ports, exp_pkt, ing_port)

def get_egr_list(parent, of_ports, how_many, exclude_list=[]):
    """
    Generate a list of ports avoiding those in the exclude list
    @param parent Supplies logging
    @param of_ports List of OF port numbers
    @param how_many Number of ports to be added to the list
    @param exclude_list List of ports not to be used
    @returns An empty list if unable to find enough ports
    """

    if how_many == 0:
        return []

    count = 0
    egr_ports = []
    for egr_idx in range(len(of_ports)): 
        if of_ports[egr_idx] not in exclude_list:
            egr_ports.append(of_ports[egr_idx])
            count += 1
            if count >= how_many:
                return egr_ports
    logging.debug("Could not generate enough egress ports for test")
    return []
    
def flow_match_test(parent, port_map, wildcards=None, vlan_vid=-1, pkt=None, 
                    exp_pkt=None, action_list=None,
                    max_test=0, egr_count=1, ing_port=False):
    """
    Run flow_match_test_port_pair on all port pairs and packet-out

    @param max_test If > 0 no more than this number of tests are executed.
    @param parent Must implement controller, dataplane, assertTrue, assertEqual
    and logging
    @param pkt If not None, use this packet for ingress
    @param wildcards For flow match entry
    @param vlan_vid If not -1, and pkt is None, create a pkt w/ VLAN tag
    @param exp_pkt If not None, use this as the expected output pkt; els use pkt
    @param action_list Additional actions to add to flow mod
    @param egr_count Number of egress ports; -1 means get from config w/ dflt 2
    """
    if wildcards is None:
        wildcards = required_wildcards(parent)
    of_ports = port_map.keys()
    of_ports.sort()
    parent.assertTrue(len(of_ports) > 1, "Not enough ports for test")
    test_count = 0

    if egr_count == -1:
        egr_count = test_param_get('egr_count', default=2)
    
    for ing_idx in range(len(of_ports)):
        ingress_port = of_ports[ing_idx]
        egr_ports = get_egr_list(parent, of_ports, egr_count, 
                                 exclude_list=[ingress_port])
        if ing_port:
            egr_ports.append(ofp.OFPP_IN_PORT)
        if len(egr_ports) == 0:
            parent.assertTrue(0, "Failed to generate egress port list")

        flow_match_test_port_pair(parent, ingress_port, egr_ports, 
                                  wildcards=wildcards, vlan_vid=vlan_vid, 
                                  pkt=pkt, exp_pkt=exp_pkt,
                                  action_list=action_list)
        test_count += 1
        if (max_test > 0) and (test_count > max_test):
            logging.info("Ran " + str(test_count) + " tests; exiting")
            break

    if not test_param_get('pktout_actions', default=True):
        return

    ingress_port = of_ports[0]
    egr_ports = get_egr_list(parent, of_ports, egr_count,
                             exclude_list=[ingress_port])
    if ing_port:
        egr_ports.append(ofp.OFPP_IN_PORT)
    flow_match_test_pktout(parent, ingress_port, egr_ports,
                           vlan_vid=vlan_vid,
                           pkt=pkt, exp_pkt=exp_pkt,
                           action_list=action_list)

def test_param_get(key, default=None):
    """
    Return value passed via test-params if present

    @param key The lookup key
    @param default Default value to use if not found

    If the pair 'key=val' appeared in the string passed to --test-params
    on the command line, return val (as interpreted by exec).  Otherwise
    return default value.

    WARNING: TEST PARAMETERS MUST BE PYTHON IDENTIFIERS; 
    eg egr_count, not egr-count.
    """
    try:
        exec oftest.config["test_params"]
    except:
        return default

    s = "val = " + str(key)
    try:
        exec s
        return val
    except:
        return default

def action_generate(parent, field_to_mod, mod_field_vals):
    """
    Create an action to modify the field indicated in field_to_mod

    @param parent Must implement, assertTrue
    @param field_to_mod The field to modify as a string name
    @param mod_field_vals Hash of values to use for modified values
    """

    act = None

    if field_to_mod in ['pktlen']:
        return None

    if field_to_mod == 'eth_dst':
        act = ofp.action.set_dl_dst()
        act.dl_addr = oftest.parse.parse_mac(mod_field_vals['eth_dst'])
    elif field_to_mod == 'eth_src':
        act = ofp.action.set_dl_src()
        act.dl_addr = oftest.parse.parse_mac(mod_field_vals['eth_src'])
    elif field_to_mod == 'dl_vlan_enable':
        if not mod_field_vals['dl_vlan_enable']: # Strip VLAN tag
            act = ofp.action.strip_vlan()
        # Add VLAN tag is handled by vlan_vid field
        # Will return None in this case
    elif field_to_mod == 'vlan_vid':
        act = ofp.action.set_vlan_vid()
        act.vlan_vid = mod_field_vals['vlan_vid']
    elif field_to_mod == 'vlan_pcp':
        act = ofp.action.set_vlan_pcp()
        act.vlan_pcp = mod_field_vals['vlan_pcp']
    elif field_to_mod == 'ip_src':
        act = ofp.action.set_nw_src()
        act.nw_addr = oftest.parse.parse_ip(mod_field_vals['ip_src'])
    elif field_to_mod == 'ip_dst':
        act = ofp.action.set_nw_dst()
        act.nw_addr = oftest.parse.parse_ip(mod_field_vals['ip_dst'])
    elif field_to_mod == 'ip_tos':
        act = ofp.action.set_nw_tos()
        act.nw_tos = mod_field_vals['ip_tos']
    elif field_to_mod == 'tcp_sport':
        act = ofp.action.set_tp_src()
        act.tp_port = mod_field_vals['tcp_sport']
    elif field_to_mod == 'tcp_dport':
        act = ofp.action.set_tp_dst()
        act.tp_port = mod_field_vals['tcp_dport']
    elif field_to_mod == 'udp_sport':
        act = ofp.action.set_tp_src()
        act.tp_port = mod_field_vals['udp_sport']
    elif field_to_mod == 'udp_dport':
        act = ofp.action.set_tp_dst()
        act.tp_port = mod_field_vals['udp_dport']
    else:
        parent.assertTrue(0, "Unknown field to modify: " + str(field_to_mod))

    return act

def pkt_action_setup(parent, start_field_vals={}, mod_field_vals={}, 
                     mod_fields=[], tp="tcp", check_test_params=False):
    """
    Set up the ingress and expected packet and action list for a test

    @param parent Must implement assertTrue
    @param start_field_values Field values to use for ingress packet (optional)
    @param mod_field_values Field values to use for modified packet (optional)
    @param mod_fields The list of fields to be modified by the switch in the test.
    @params check_test_params If True, will check the parameters vid, add_vlan
    and strip_vlan from the command line.

    Returns a triple:  pkt-to-send, expected-pkt, action-list
    """

    new_actions = []

    base_pkt_params = {}
    base_pkt_params['pktlen'] = 100
    base_pkt_params['eth_dst'] = '00:DE:F0:12:34:56'
    base_pkt_params['eth_src'] = '00:23:45:67:89:AB'
    base_pkt_params['dl_vlan_enable'] = False
    base_pkt_params['vlan_vid'] = 2
    base_pkt_params['vlan_pcp'] = 0
    base_pkt_params['ip_src'] = '192.168.0.1'
    base_pkt_params['ip_dst'] = '192.168.0.2'
    base_pkt_params['ip_tos'] = 0
    if tp == "tcp":
        base_pkt_params['tcp_sport'] = 1234
        base_pkt_params['tcp_dport'] = 80
    elif tp == "udp":
        base_pkt_params['udp_sport'] = 1234
        base_pkt_params['udp_dport'] = 80
    for keyname in start_field_vals.keys():
        base_pkt_params[keyname] = start_field_vals[keyname]

    mod_pkt_params = {}
    mod_pkt_params['pktlen'] = 100
    mod_pkt_params['eth_dst'] = '00:21:0F:ED:CB:A9'
    mod_pkt_params['eth_src'] = '00:ED:CB:A9:87:65'
    mod_pkt_params['dl_vlan_enable'] = False
    mod_pkt_params['vlan_vid'] = 3
    mod_pkt_params['vlan_pcp'] = 7
    mod_pkt_params['ip_src'] = '10.20.30.40'
    mod_pkt_params['ip_dst'] = '50.60.70.80'
    mod_pkt_params['ip_tos'] = 0xf0
    if tp == "tcp":
        mod_pkt_params['tcp_sport'] = 4321
        mod_pkt_params['tcp_dport'] = 8765
    elif tp == "udp":
        mod_pkt_params['udp_sport'] = 4321
        mod_pkt_params['udp_dport'] = 8765
    for keyname in mod_field_vals.keys():
        mod_pkt_params[keyname] = mod_field_vals[keyname]

    # Check for test param modifications
    strip = False
    if check_test_params:
        add_vlan = test_param_get('add_vlan')
        strip_vlan = test_param_get('strip_vlan')
        vid = test_param_get('vid')

        if add_vlan and strip_vlan:
            parent.assertTrue(0, "Add and strip VLAN both specified")

        if vid:
            base_pkt_params['dl_vlan_enable'] = True
            base_pkt_params['vlan_vid'] = vid
            if 'vlan_vid' in mod_fields:
                mod_pkt_params['vlan_vid'] = vid + 1

        if add_vlan:
            base_pkt_params['dl_vlan_enable'] = False
            mod_pkt_params['dl_vlan_enable'] = True
            mod_pkt_params['pktlen'] = base_pkt_params['pktlen'] + 4
            mod_fields.append('pktlen')
            mod_fields.append('dl_vlan_enable')
            if 'vlan_vid' not in mod_fields:
                mod_fields.append('vlan_vid')
        elif strip_vlan:
            base_pkt_params['dl_vlan_enable'] = True
            mod_pkt_params['dl_vlan_enable'] = False
            mod_pkt_params['pktlen'] = base_pkt_params['pktlen'] - 4
            mod_fields.append('dl_vlan_enable')
            mod_fields.append('pktlen')

    if tp == "tcp":
        packet_builder = simple_tcp_packet
    elif tp == "udp":
        packet_builder = simple_udp_packet
    else:
        raise NotImplementedError("unknown transport protocol %s" % tp)

    # Build the ingress packet
    ingress_pkt = packet_builder(**base_pkt_params)

    # Build the expected packet, modifying the indicated fields
    for item in mod_fields:
        base_pkt_params[item] = mod_pkt_params[item]
        act = action_generate(parent, item, mod_pkt_params)
        if act:
            new_actions.append(act)

    expected_pkt = packet_builder(**base_pkt_params)

    return (ingress_pkt, expected_pkt, new_actions)

# Generate a simple "drop" flow mod
# If in_band is true, then only drop from first test port
def flow_mod_gen(port_map, in_band):
    request = ofp.message.flow_add()
    request.match.wildcards = ofp.OFPFW_ALL
    if in_band:
        request.match.wildcards = ofp.OFPFW_ALL - ofp.OFPFW_IN_PORT
        for of_port, ifname in port_map.items(): # Grab first port
            break
        request.match.in_port = of_port
    request.buffer_id = 0xffffffff
    return request

def skip_message_emit(parent, s):
    """
    Print out a 'skipped' message to stderr

    @param s The string to print out to the log file
    """
    global skipped_test_count

    skipped_test_count += 1
    logging.info("Skipping: " + s)
    if oftest.config["debug"] < logging.WARNING:
        sys.stderr.write("(skipped) ")
    else:
        sys.stderr.write("(S)")


def all_stats_get(parent):
    """
    Get the aggregate stats for all flows in the table
    @param parent Test instance with controller connection and assert
    @returns dict with keys flows, packets, bytes, active (flows), 
    lookups, matched
    """
    stat_req = ofp.message.aggregate_stats_request()
    stat_req.match = ofp.match()
    stat_req.match.wildcards = ofp.OFPFW_ALL
    stat_req.table_id = 0xff
    stat_req.out_port = ofp.OFPP_NONE

    rv = {}

    (reply, pkt) = parent.controller.transact(stat_req)
    parent.assertTrue(len(reply.entries) == 1, "Did not receive flow stats reply")

    for obj in reply.entries:
        (rv["flows"], rv["packets"], rv["bytes"]) = (obj.flow_count, 
                                                  obj.packet_count, obj.byte_count)
        break

    request = ofp.message.table_stats_request()
    (reply , pkt) = parent.controller.transact(request)

    
    (rv["active"], rv["lookups"], rv["matched"]) = (0,0,0)
    for obj in reply.entries:
        rv["active"] += obj.active_count
        rv["lookups"] += obj.lookup_count
        rv["matched"] += obj.matched_count

    return rv

_import_blacklist.add('FILTER')
FILTER=''.join([(len(repr(chr(x)))==3) and chr(x) or '.' 
                for x in range(256)])

def hex_dump_buffer(src, length=16):
    """
    Convert src to a hex dump string and return the string
    @param src The source buffer
    @param length The number of bytes shown in each line
    @returns A string showing the hex dump
    """
    result = ["\n"]
    for i in xrange(0, len(src), length):
       chars = src[i:i+length]
       hex = ' '.join(["%02x" % ord(x) for x in chars])
       printable = ''.join(["%s" % ((ord(x) <= 127 and
                                     FILTER[ord(x)]) or '.') for x in chars])
       result.append("%04x  %-*s  %s\n" % (i, length*3, hex, printable))
    return ''.join(result)

def format_packet(pkt):
    return "Packet length %d \n%s" % (len(str(pkt)), 
                                      hex_dump_buffer(str(pkt)))

def inspect_packet(pkt):
    """
    Wrapper around scapy's show() method.
    @returns A string showing the dissected packet.
    """
    from cStringIO import StringIO
    out = None
    backup = sys.stdout
    try:
        sys.stdout = StringIO()
        pkt.show2()
        out = sys.stdout.getvalue()
        sys.stdout.close()
    finally:
        sys.stdout = backup
    return out

def nonstandard(cls):
    """
    Testcase decorator that marks the test as being non-standard.
    These tests are not automatically added to the "standard" group.
    """
    cls._nonstandard = True
    return cls

def disabled(cls):
    """
    Testcase decorator that marks the test as being disabled.
    These tests are not automatically added to the "standard" group or
    their module's group.
    """
    cls._disabled = True
    return cls

def group(name):
    """
    Testcase decorator that adds the test to a group.
    """
    def fn(cls):
        if not hasattr(cls, "_groups"):
            cls._groups = []
        cls._groups.append(name)
        return cls
    return fn

def version(ver):
    """
    Testcase decorator that specifies which versions of OpenFlow the test
    supports. The default is 1.0+. This decorator may only be used once.

    Supported syntax:
    1.0 -> 1.0
    1.0,1.2,1.3 -> 1.0, 1.2, 1.3
    1.0+ -> 1.0, 1.1, 1.2, 1.3
    """
    versions = parse_version(ver)
    def fn(cls):
        cls._versions = versions
        return cls
    return fn

def parse_version(ver):
    allowed_versions = ["1.0", "1.1", "1.2", "1.3"]
    if re.match("^1\.\d+$", ver):
        versions = set([ver])
    elif re.match("^(1\.\d+)\+$", ver):
        if not ver[:-1] in allowed_versions:
            raise ValueError("invalid OpenFlow version %s" % ver[:-1])
        versions = set()
        if ver != "1.1+": versions.add("1.0")
        if ver != "1.2+": versions.add("1.1")
        if ver != "1.3+": versions.add("1.2")
        versions.add("1.3")
    else:
        versions = set(ver.split(','))

    for version in versions:
        if not version in allowed_versions:
            raise ValueError("invalid OpenFlow version %s" % version)

    return versions

assert(parse_version("1.0") == set(["1.0"]))
assert(parse_version("1.0,1.2,1.3") == set(["1.0", "1.2", "1.3"]))
assert(parse_version("1.0+") == set(["1.0", "1.1", "1.2", "1.3"]))

def get_stats(test, req):
    """
    Retrieve a list of stats entries. Handles OFPSF_REPLY_MORE.
    """
    stats = []
    reply, _ = test.controller.transact(req)
    test.assertTrue(reply is not None, "No response to stats request")
    stats.extend(reply.entries)
    while reply.flags & ofp.OFPSF_REPLY_MORE != 0:
        reply, pkt = self.controller.poll(exp_msg=ofp.OFPT_STATS_REPLY)
        test.assertTrue(reply is not None, "No response to stats request")
        stats.extend(reply.entries)
    return stats

def get_flow_stats(test, match, table_id=0xff, out_port=ofp.OFPP_NONE):
    """
    Retrieve a list of flow stats entries.
    """
    req = ofp.message.flow_stats_request(match=match,
                                          table_id=table_id,
                                          out_port=out_port)
    return get_stats(test, req)

def get_port_stats(test, port_no):
    """
    Retrieve a list of port stats entries.
    """
    req = ofp.message.port_stats_request(port_no=port_no)
    return get_stats(test, req)

def get_queue_stats(test, port_no, queue_id):
    """
    Retrieve a list of queue stats entries.
    """
    req = ofp.message.queue_stats_request(port_no=port_no, queue_id=queue_id)
    return get_stats(test, req)

def verify_flow_stats(test, match, table_id=0xff,
                      out_port=ofp.OFPP_NONE,
                      initial=[],
                      pkts=None, bytes=None):
    """
    Verify that flow stats changed as expected.

    Optionally takes an 'initial' list of stats entries, as returned by
    get_flow_stats(). If 'initial' is not given the counters are assumed to
    begin at 0.
    """
    def accumulate(stats):
        pkts_acc = bytes_acc = 0
        for stat in stats:
            pkts_acc += stat.packet_count
            bytes_acc += stat.byte_count
        return (pkts_acc, bytes_acc)

    pkts_before, bytes_before = accumulate(initial)

    # Wait 10s for counters to update
    pkt_diff = byte_diff = None
    for i in range(0, 100):
        stats = get_flow_stats(test, match, table_id=table_id, out_port=out_port)
        pkts_after, bytes_after = accumulate(stats)
        pkt_diff = pkts_after - pkts_before
        byte_diff = bytes_after - bytes_before
        if (pkts == None or pkt_diff >= pkts) and \
           (bytes == None or byte_diff >= bytes):
            break
        time.sleep(0.1)

    if pkts != None:
        test.assertEquals(pkt_diff, pkts, "Flow packet counter not updated properly (expected increase of %d, got increase of %d)" % (pkts, pkt_diff))

    if bytes != None:
        test.assertTrue(byte_diff >= bytes and byte_diff <= bytes*1.1,
                        "Flow byte counter not updated properly (expected increase of %d, got increase of %d)" % (bytes, byte_diff))

def verify_port_stats(test, port,
                      initial=[],
                      tx_pkts=None, rx_pkts=None,
                      tx_bytes=None, rx_bytes=None):
    """
    Verify that port stats changed as expected.

    Optionally takes an 'initial' list of stats entries, as returned by
    get_port_stats(). If 'initial' is not given the counters are assumed to
    begin at 0.
    """
    def accumulate(stats):
        tx_pkts_acc = rx_pkts_acc = tx_bytes_acc = rx_bytes_acc = 0
        for stat in stats:
            tx_pkts_acc += stat.tx_packets
            rx_pkts_acc += stat.rx_packets
            tx_bytes_acc += stat.tx_bytes
            rx_bytes_acc += stat.rx_bytes
        return (tx_pkts_acc, rx_pkts_acc, tx_bytes_acc, rx_bytes_acc)

    tx_pkts_before, rx_pkts_before, \
        tx_bytes_before, rx_bytes_before = accumulate(initial)

    # Wait 10s for counters to update
    for i in range(0, 100):
        stats = get_port_stats(test, port)
        tx_pkts_after, rx_pkts_after, \
            tx_bytes_after, rx_bytes_after = accumulate(stats)
        tx_pkts_diff = tx_pkts_after - tx_pkts_before
        rx_pkts_diff = rx_pkts_after - rx_pkts_before
        tx_bytes_diff = tx_bytes_after - tx_bytes_before
        rx_bytes_diff = rx_bytes_after - rx_bytes_before
        if (tx_pkts == None or tx_pkts == tx_pkts_diff) and \
           (rx_pkts == None or rx_pkts == rx_pkts_diff) and \
           (tx_bytes == None or tx_bytes <= tx_bytes_diff) and \
           (rx_bytes == None or rx_bytes <= rx_bytes_diff):
            break
        time.sleep(0.1)

    if (tx_pkts != None):
        test.assertEqual(tx_pkts,tx_pkts_diff,"Port TX packet counter is not updated correctly (expected increase of %d, got increase of %d)" % (tx_pkts, tx_pkts_diff))
    if (rx_pkts != None):
        test.assertEqual(rx_pkts,rx_pkts_diff,"Port RX packet counter is not updated correctly (expected increase of %d, got increase of %d)" % (rx_pkts, rx_pkts_diff))
    if (tx_bytes != None):
        test.assertTrue(tx_bytes_diff >= tx_bytes and tx_bytes_diff <= tx_bytes*1.1,
                        "Port TX byte counter is not updated correctly (expected increase of %d, got increase of %d)" % (tx_bytes, tx_bytes_diff))
    if (rx_bytes != None):
        test.assertTrue(rx_bytes_diff >= rx_bytes and rx_bytes_diff <= rx_bytes*1.1,
                        "Port RX byte counter is not updated correctly (expected increase of %d, got increase of %d)" % (rx_bytes, rx_bytes_diff))

def verify_queue_stats(test, port_no, queue_id,
                       initial=[],
                       pkts=None, bytes=None):
    """
    Verify that queue stats changed as expected.

    Optionally takes an 'initial' list of stats entries, as returned by
    get_queue_stats(). If 'initial' is not given the counters are assumed to
    begin at 0.
    """
    def accumulate(stats):
        pkts_acc = bytes_acc = 0
        for stat in stats:
            pkts_acc += stat.tx_packets
            bytes_acc += stat.tx_bytes
        return (pkts_acc, bytes_acc)

    pkts_before, bytes_before = accumulate(initial)

    # Wait 10s for counters to update
    pkt_diff = byte_diff = None
    for i in range(0, 100):
        stats = get_queue_stats(test, port_no, queue_id)
        pkts_after, bytes_after = accumulate(stats)
        pkt_diff = pkts_after - pkts_before
        byte_diff = bytes_after - bytes_before
        if (pkts == None or pkt_diff >= pkts) and \
           (bytes == None or byte_diff >= bytes):
            break
        time.sleep(0.1)

    if pkts != None:
        test.assertEquals(pkt_diff, pkts, "Queue packet counter not updated properly (expected increase of %d, got increase of %d)" % (pkts, pkt_diff))

    if bytes != None:
        test.assertTrue(byte_diff >= bytes and byte_diff <= bytes*1.1,
                        "Queue byte counter not updated properly (expected increase of %d, got increase of %d)" % (bytes, byte_diff))

__all__ = list(set(locals()) - _import_blacklist)
