'''
OFTests for functionality needed from the OLT.
'''
import logging
from __builtin__ import xrange
from oftest import config
import oftest.base_tests as base_tests
import oftest.packet as scapy

import ofp
import time
import copy

from oftest.testutils import *

onu_port = test_param_get("onu_port", 130)
onu_port2 = test_param_get("onu_port2", 130)
olt_port = test_param_get("olt_port", 258)


def double_vlan_udp_packet(pktlen=100,
                           eth_dst='00:01:02:03:04:05',
                           eth_src='00:06:07:08:09:0a',
                           dl_vlan_enable=False,
                           c_vlan_vid=0,
                           c_vlan_pcp=0,
                           s_vlan_vid=0,
                           s_vlan_pcp=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,
                           eth_type=0x8100
                           ):
    """
    Return a double vlan tagged 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 c_vlan_vid CVLAN ID
    @param c_vlan_pcp CVLAN priority
    @param s_vlan_vid SVLAN ID
    @param s_vlan_pcp SVLAN 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, type=eth_type) / \
              scapy.Dot1Q(prio=s_vlan_pcp, vlan=s_vlan_vid) / \
              scapy.Dot1Q(prio=c_vlan_pcp, vlan=c_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 testPacketIn(self, match, parsed_pkt):
    delete_all_flows(self.controller)

    pkt = str(parsed_pkt)

    for of_port in config["port_map"]:
        m = copy.deepcopy(match)
        m.oxm_list.append(ofp.oxm.in_port(of_port))
        request = ofp.message.flow_add(
            table_id=test_param_get("table", 0),
            cookie=42,
            match=m,
            instructions=[
                ofp.instruction.apply_actions(
                    actions=[
                        ofp.action.output(
                            port=ofp.OFPP_CONTROLLER,
                            max_len=ofp.OFPCML_NO_BUFFER)])],
            buffer_id=ofp.OFP_NO_BUFFER,
            priority=1000)
        logging.info("Inserting flow sending matching packets to controller")
        self.controller.message_send(request)
        do_barrier(self.controller)

    for of_port in config["port_map"]:
        logging.info("PacketInExact test, port %d", of_port)
        self.dataplane.send(of_port, pkt)
        verify_packet_in(self, pkt, of_port, ofp.OFPR_ACTION)
        verify_packets(self, pkt, [])


def buildIgmp(payload):
    ether = scapy.Ether(src="00:01:02:03:04:05")
    ip = scapy.IP(src="1.2.3.4")
    payload.igmpize(ip, ether)
    pkt = ether / ip / payload
    if len(pkt) < 60:
        pad_len = 60 - len(pkt)
        pad = scapy.PAD()
        pad.load = '\x00' * pad_len
        pkt = pkt / pad
    return pkt


class EapolPacketIn(base_tests.SimpleDataPlane):
    """Verify packet-ins are sent for EAPOL packets """

    def runTest(self):
        logging.info("Running EAPOL Packet In test")

        match = ofp.match()
        match.oxm_list.append(ofp.oxm.eth_type(0x888e))
        # Use ethertype 0x888e and multicast destination MAC address
        pkt = simple_eth_packet(pktlen=60, eth_dst='01:00:5E:7F:FF:FF', eth_type=0x888e)

        testPacketIn(self, match, pkt)






class IGMPPacketIn(base_tests.SimpleDataPlane):
    """Verify packet-ins are sent for IGMP packets """

    def runTest(self):
        logging.info("Running IGMP Packet In test")

        match = ofp.match()
        match.oxm_list.append(ofp.oxm.eth_type(0x800))
        match.oxm_list.append(ofp.oxm.ip_proto(2))

        pkt = scapy.Ether(dst='01:00:5E:7F:FF:FF', src='00:00:00:00:00:01') / \
              scapy.IP(src='10.0.0.1', dst='10.0.0.2', ttl=60, tos=0, id=0, proto=2)

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

        testPacketIn(self, match, pkt)


class IGMPQueryPacketOut(base_tests.SimpleDataPlane):
    """Verify sending multicast membership queries down to onu_ports"""

    def runTest(self):
        logging.info("Running IGMP query packet out")

        igmp = scapy.IGMP(type=0x11, gaddr="224.0.0.1")
        pkt = buildIgmp(igmp)

        msg = ofp.message.packet_out()
        msg.in_port = ofp.OFPP_CONTROLLER
        msg.buffer_id = 0xffffffff
        msg.data = str(pkt)
        msg.actions = [ofp.action.output(
            port=onu_port,
            max_len=ofp.OFPCML_NO_BUFFER)]
        time.sleep(1)

        self.controller.message_send(msg)

        verify_no_errors(self.controller)

        verify_packet(self, pkt, onu_port)


class TestMeter(base_tests.SimpleDataPlane):
    def runTest(self):
        logging.info("Running Meter tests")
        dropMeterBand = ofp.meter_band.drop(rate=640)
        meter_mod = ofp.message.meter_mod(xid=1, command=ofp.OFPMC_ADD, meter_id=1, meters=[dropMeterBand])
        self.controller.message_send(meter_mod)

        time.sleep(1)

        verify_no_errors(self.controller)

        vlan_id = 201
        match = ofp.match()
        match.oxm_list.append(ofp.oxm.in_port(onu_port))
        match.oxm_list.append(ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT | vlan_id))

        request = ofp.message.flow_add(
            table_id=test_param_get("table", 0),
            cookie=42,
            match=match,
            instructions=[
                ofp.instruction.apply_actions(
                    actions=[ofp.action.output(port=olt_port)]
                ),
                ofp.instruction.meter(meter_id=1)
            ],
            buffer_id=ofp.OFP_NO_BUFFER,
            priority=1000)

        self.controller.message_send(request)
        time.sleep(1)
        verify_no_errors(self.controller)

        match = ofp.match()
        match.oxm_list.append(ofp.oxm.in_port(olt_port))
        match.oxm_list.append(ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT | vlan_id))

        request = ofp.message.flow_add(
            table_id=test_param_get("table", 0),
            cookie=43,
            match=match,
            instructions=[
                ofp.instruction.apply_actions(
                    actions=[ofp.action.output(port=onu_port)]
                ),
                ofp.instruction.meter(meter_id=1)
            ],
            buffer_id=ofp.OFP_NO_BUFFER,
            priority=1000)

        self.controller.message_send(request)
        time.sleep(1)
        verify_no_errors(self.controller)
        do_barrier(self.controller)
        time.sleep(5)

        inPkt = simple_udp_packet(dl_vlan_enable=True, vlan_vid=vlan_id, vlan_pcp=0)
        # downstream
        # self.dataplane.send(olt_port, str(inPkt))
        # verify_packet(self, inPkt, onu_port)
        # upstream
        # for i in range(1,400):
        #	self.dataplane.send(onu_port, str(inPkt))
        # verify_packet(self, inPkt, olt_port)

        # clean up the test
        meter_mod = ofp.message.meter_mod(xid=2, command=ofp.OFPMC_DELETE, meter_id=1)
        self.controller.message_send(meter_mod)
        time.sleep(1)
        delete_all_flows(self.controller)
        verify_no_errors(self.controller)


class TestDuplicateMeter(base_tests.SimpleDataPlane):
    def runTest(self):
        logging.info("Running Duplicate Meter Test")
        dropMeterBand = ofp.meter_band.drop(rate=500)
        meter_mod = ofp.message.meter_mod(xid=1, command=ofp.OFPMC_ADD, meter_id=1, meters=[dropMeterBand])
        self.controller.message_send(meter_mod)
        self.controller.message_send(meter_mod)

        time.sleep(1)

        try:
            verify_no_errors(self.controller)
        except AssertionError as e:
            if (not e.message == "unexpected error type=12 code=1"):
                raise AssertionError("Incorrect error type: %s" % e.message)


class VlanTest(base_tests.SimpleDataPlane):
    """Verify the switch can push/pop a VLAN tag and forward out a port """

    def runTest(self):
        logging.info("Running push VLAN test")

        vlan_id = 200

        delete_all_flows(self.controller)

        # PUSH
        match = ofp.match()
        match.oxm_list.append(ofp.oxm.in_port(onu_port))
        match.oxm_list.append(ofp.oxm.vlan_vid_masked(value=ofp.OFPVID_PRESENT, value_mask=ofp.OFPVID_PRESENT))
        match.oxm_list.append(ofp.oxm.vlan_pcp(value=0))

        request = ofp.message.flow_add(
            table_id=test_param_get("table", 0),
            cookie=42,
            match=match,
            instructions=[
                ofp.instruction.apply_actions(
                    actions=[
                        ofp.action.push_vlan(ethertype=0x8100),
                        ofp.action.set_field(ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT | vlan_id)),
                        ofp.action.set_field(ofp.oxm.vlan_pcp(0)),
                        ofp.action.output(port=olt_port)])],
            buffer_id=ofp.OFP_NO_BUFFER,
            priority=1000)

        logging.info("Inserting flow tagging upstream")
        self.controller.message_send(request)

        # POP
        match = ofp.match()
        match.oxm_list.append(ofp.oxm.in_port(olt_port))
        match.oxm_list.append(ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT | vlan_id))

        request = ofp.message.flow_add(
            table_id=test_param_get("table", 0),
            cookie=43,
            match=match,
            instructions=[
                ofp.instruction.apply_actions(
                    actions=[
                        ofp.action.pop_vlan(),
                        ofp.action.output(port=onu_port)])],
            buffer_id=ofp.OFP_NO_BUFFER,
            priority=1000)

        logging.info("Inserting flow tagging downstream")
        self.controller.message_send(request)
        do_barrier(self.controller)
        time.sleep(5)

        inPkt = simple_udp_packet(dl_vlan_enable=True, vlan_vid=0, vlan_pcp=0)
        outPkt = simple_udp_packet(pktlen=100, dl_vlan_enable=True,
                                   vlan_vid=vlan_id, vlan_pcp=0, dl_vlan_cfi=0)

        # Send untagged packet in the ONU port and expect tagged packet out the OLT port
        self.dataplane.send(onu_port, str(inPkt))
        verify_packet(self, outPkt, olt_port)

        # Send untagged packet in the OLT port and expect no packets to come out
        self.dataplane.send(olt_port, str(inPkt))
        verify_packets(self, outPkt, [])

        inPkt = simple_udp_packet(pktlen=104, dl_vlan_enable=True,
                                  vlan_vid=vlan_id, vlan_pcp=0, dl_vlan_cfi=0)
        outPkt = simple_udp_packet(pktlen=104, dl_vlan_enable=True, vlan_vid=0, vlan_pcp=0)

        # Send tagged packet in the OLT port and expect untagged packet out the OLT port
        self.dataplane.send(olt_port, str(inPkt))
        verify_packet(self, outPkt, onu_port)

        # Send tagged packet in the ONU port and expect no packets to come out
        self.dataplane.send(onu_port, str(inPkt))
        verify_packets(self, outPkt, [])


def createAllGroupAdd(group_id, ports=[]):
    buckets = []

    for portNum in ports:
        buckets.append(ofp.common.bucket(watch_port=ofp.OFPP_ANY, watch_group=ofp.OFPG_ANY,
                                         actions=[ofp.action.pop_vlan(), ofp.action.output(port=portNum)]))

    group_add = ofp.message.group_add(group_type=ofp.OFPGT_ALL, group_id=group_id, buckets=buckets)

    return group_add


def createAllGroupMod(group_id, ports=[]):
    buckets = []

    for portNum in ports:
        buckets.append(ofp.common.bucket(watch_port=ofp.OFPP_ANY, watch_group=ofp.OFPG_ANY,
                                         actions=[ofp.action.output(port=portNum)]))

    group_mod = ofp.message.group_mod(command=ofp.OFPGC_MODIFY, group_type=ofp.OFPGT_ALL, group_id=group_id,
                                      buckets=buckets)

    return group_mod


class TestGroupAdd(base_tests.SimpleDataPlane):
    def runTest(self):
        logging.info("Running Group tests")
        delete_all_flows(self.controller)
        delete_all_groups(self.controller)

        test_group_id = 1

        # output to two ONU
        group_add = createAllGroupAdd(test_group_id, ports=[onu_port, onu_port2])

        self.controller.message_send(group_add)
        do_barrier(self.controller)
        verify_no_errors(self.controller)

        # Remove the group and then readd it.
        group_delete = ofp.message.group_delete(group_id=test_group_id)
        self.controller.message_send(group_delete)
        do_barrier(self.controller)
        verify_no_errors(self.controller)

        group_add = createAllGroupAdd(test_group_id, [onu_port, onu_port2])
        self.controller.message_send(group_add)
        do_barrier(self.controller)
        verify_no_errors(self.controller)


        # clean up the test
        group_delete = ofp.message.group_delete(group_id=test_group_id)
        self.controller.message_send(group_delete)

        do_barrier(self.controller)
        verify_no_errors(self.controller)


class TestGroupMod(base_tests.SimpleDataPlane):
    def runTest(self):
        logging.info("Running Group tests")
        delete_all_flows(self.controller)
        delete_all_groups(self.controller)

        test_group_id = 1

        group_add = createAllGroupAdd(test_group_id, [onu_port, onu_port2])

        self.controller.message_send(group_add)
        do_barrier(self.controller)
        verify_no_errors(self.controller)

        # Modifying the group
        group_mod = createAllGroupMod(test_group_id, [onu_port2])

        self.controller.message_send(group_mod)
        do_barrier(self.controller)
        verify_no_errors(self.controller)

        # Add a bucket into the group
        group_mod = createAllGroupMod(test_group_id, [onu_port, onu_port2])
        self.controller.message_send(group_mod)
        do_barrier(self.controller)
        verify_no_errors(self.controller)

        # Modifying a non-existing group
        group_mod = createAllGroupMod(777, [onu_port2])

        self.controller.message_send(group_mod)
        do_barrier(self.controller)
        errorExperienced = 0
        try:
            verify_no_errors(self.controller)
        except AssertionError as e:
            errorExperienced = 1
            if (not (e.message == "unexpected error type=6 code=8")):
                raise AssertionError("Incorrect error type: %s" % e.message)
        if not errorExperienced:
            raise AssertionError("An error message is expected, but not shown.")


        # clean up the test
        group_delete = ofp.message.group_delete(xid=2, group_id=test_group_id)
        self.controller.message_send(group_delete)

        do_barrier(self.controller)
        verify_no_errors(self.controller)


class TestDuplicateGroup(base_tests.SimpleDataPlane):
    def runTest(self):
        logging.info("Running Group tests")
        delete_all_flows(self.controller)
        delete_all_groups(self.controller)

        test_group_id = 1
        group_add = createAllGroupAdd(test_group_id, ports=[onu_port])

        self.controller.message_send(group_add)
        do_barrier(self.controller)
        verify_no_errors(self.controller)

        # Add the same group id
        duplicate_group_fail = 0

        self.controller.message_send(group_add)
        do_barrier(self.controller)
        try:
            verify_no_errors(self.controller)
        except AssertionError as e:
            duplicate_group_fail = 1
            if (not e.message == "unexpected error type=6 code=0"):
                raise AssertionError("Incorrect error type: %s" % e.message)
        if not duplicate_group_fail:
            raise AssertionError("Adding duplicate groups didn't raise an error.")

        # clean up the test
        group_delete = ofp.message.group_delete(xid=2, group_id=test_group_id)
        self.controller.message_send(group_delete)

        do_barrier(self.controller)
        verify_no_errors(self.controller)


class TestGroupAndFlow(base_tests.SimpleDataPlane):
    def runTest(self):
        logging.info("Running Group tests")
        delete_all_flows(self.controller)
        delete_all_groups(self.controller)

        # Create a group
        test_group_id = 1
        group_add = createAllGroupAdd(test_group_id, ports=[onu_port])

        self.controller.message_send(group_add)
        do_barrier(self.controller)
        verify_no_errors(self.controller)

        # Create a flow rule matching olt port and vlan id
        match = ofp.match()
        match.oxm_list.append(ofp.oxm.in_port(olt_port))
        match.oxm_list.append(ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT | 201))

        flow_pointing_to_group = ofp.message.flow_add(
            table_id=test_param_get("table", 0),
            cookie=43,
            match=match,
            instructions=[
                ofp.instruction.apply_actions(
                    actions=[ofp.action.group(group_id=test_group_id)])],
            buffer_id=ofp.OFP_NO_BUFFER, priority=1000)

        self.controller.message_send(flow_pointing_to_group)
        do_barrier(self.controller)
        verify_no_errors(self.controller)

        # After letting a flow rule point to the group, test we can do group_mod
        group_mod = createAllGroupMod(test_group_id, ports=[onu_port2])
        self.controller.message_send(group_mod)
        do_barrier(self.controller)
        verify_no_errors(self.controller)

        # Test we can remove flows and then remove group
        flow_delete = ofp.message.flow_delete(table_id=test_param_get("table", 0))
        self.controller.message_send(flow_delete)
        do_barrier(self.controller)
        verify_no_errors(self.controller)

        group_delete = ofp.message.group_delete(xid=3, group_id=test_group_id)
        self.controller.message_send(group_delete)
        do_barrier(self.controller)
        verify_no_errors(self.controller)

        # Add the group and flow back, test it we can first remove group and then remove the flow. 
        '''group_add = createAllGroupAdd(test_group_id, ports=[onu_port])
        self.controller.message_send(group_add)

        self.controller.message_send(flow_pointing_to_group)
        do_barrier(self.controller)
        verify_no_errors(self.controller)

        group_delete = ofp.message.group_delete(xid = 4, group_id = test_group_id)
        self.controller.message_send(group_delete)'''

        self.controller.message_send(flow_delete)
        do_barrier(self.controller)
        verify_no_errors(self.controller)


class TestGroupForwarding(base_tests.SimpleDataPlane):
    def runTest(self):
        logging.info("Running Group datapath forwarding tests")
        delete_all_flows(self.controller)
        delete_all_groups(self.controller)

        vlan_id = 201

        # Create a group
        test_group_id = 1
        group_add = createAllGroupAdd(test_group_id, [onu_port])

        self.controller.message_send(group_add)
        do_barrier(self.controller)
        verify_no_errors(self.controller)

        # Create a flow rule matching olt port and vlan id
        match = ofp.match()
        match.oxm_list.append(ofp.oxm.in_port(olt_port))
        match.oxm_list.append(ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT | vlan_id))

        request = ofp.message.flow_add(
            table_id=test_param_get("table", 0),
            cookie=43,
            match=match,
            instructions=[
                ofp.instruction.apply_actions(
                    actions=[ofp.action.group(group_id=test_group_id)]),
            ],
            buffer_id=ofp.OFP_NO_BUFFER, priority=1000)

        self.controller.message_send(request)
        do_barrier(self.controller)
        verify_no_errors(self.controller)

        # It takes some time for flows to propagate down to the data plane
        time.sleep(10)

        inPkt = simple_udp_packet(pktlen=104, dl_vlan_enable=True,
                                  vlan_vid=vlan_id, vlan_pcp=0, dl_vlan_cfi=0, eth_dst="01:01:11:12:11:12")
        outPkt = inPkt
        self.dataplane.send(olt_port, str(inPkt))
        verify_packet(self, outPkt, onu_port)


        # Now put 2 ONU ports in the group and test that the input packet is 
        # duplicated out both ports
        group_mod = createAllGroupMod(test_group_id, ports=[onu_port, onu_port2])
        self.controller.message_send(group_mod)
        do_barrier(self.controller)
        verify_no_errors(self.controller)

        # It takes some time for flows to propagate down to the data plane
        time.sleep(10)

        self.dataplane.send(olt_port, str(inPkt))
        verify_packet(self, outPkt, onu_port2)
        verify_packet(self, outPkt, onu_port)
        # verify_packets(self, outPkt, [onu_port,onu_port2])

        # clean up the test
        request = ofp.message.flow_delete(table_id=test_param_get("table", 0))
        self.controller.message_send(request)
        group_delete = ofp.message.group_delete(xid=2, group_id=test_group_id)
        self.controller.message_send(group_delete)

        do_barrier(self.controller)
        verify_no_errors(self.controller)


class TestGroupModForwarding(base_tests.SimpleDataPlane):
    def runTest(self):
        logging.info("Running datapath forwarding tests for group mod")
        delete_all_flows(self.controller)
        delete_all_groups(self.controller)

        vlan_id = 201

        # Create a group
        test_group_id = 1
        group_add = createAllGroupAdd(test_group_id, [onu_port, onu_port2])

        self.controller.message_send(group_add)
        do_barrier(self.controller)
        verify_no_errors(self.controller)

        # Create a flow rule matching olt port and vlan id
        match = ofp.match()
        match.oxm_list.append(ofp.oxm.in_port(olt_port))
        match.oxm_list.append(ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT | vlan_id))

        request = ofp.message.flow_add(
            table_id=test_param_get("table", 0),
            cookie=43,
            match=match,
            instructions=[
                ofp.instruction.apply_actions(
                    actions=[ofp.action.group(group_id=test_group_id)]),
            ],
            buffer_id=ofp.OFP_NO_BUFFER, priority=1000)

        self.controller.message_send(request)
        do_barrier(self.controller)
        verify_no_errors(self.controller)

        # It takes some time for flows to propagate down to the data plane
        time.sleep(10)

        inPkt = simple_udp_packet(pktlen=104, dl_vlan_enable=True,
                                  vlan_vid=vlan_id, vlan_pcp=0, dl_vlan_cfi=0, eth_dst="01:01:11:12:11:12")
        outPkt = inPkt
        self.dataplane.send(olt_port, str(inPkt))
        verify_packet(self, outPkt, onu_port)
        verify_packet(self, outPkt, onu_port2)

        # Now remove onu port 1 from the group and test that the input packet is no longer forwarded to onu port 1
        group_mod = createAllGroupMod(test_group_id, ports=[onu_port2])
        self.controller.message_send(group_mod)
        do_barrier(self.controller)
        verify_no_errors(self.controller)

        time.sleep(10)
        self.dataplane.send(olt_port, str(inPkt))
        verify_no_packet(self, outPkt, onu_port)
        verify_packet(self, outPkt, onu_port2)

        # Now remove all ports in the group and test that the input packet is no longer forwarded to any port 
        group_mod = createAllGroupMod(test_group_id, ports=[])
        self.controller.message_send(group_mod)
        do_barrier(self.controller)
        verify_no_errors(self.controller)
        time.sleep(10)
        self.dataplane.send(olt_port, str(inPkt))
        verify_packets(self, outPkt, [])


class TransparentVlanTest(base_tests.SimpleDataPlane):
    def runTest(self):
        logging.info("Running transparent vlan tests")
        delete_all_flows(self.controller)

        vlan_id = 201
        match = ofp.match()
        match.oxm_list.append(ofp.oxm.in_port(onu_port))
        match.oxm_list.append(ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT | vlan_id))

        request = ofp.message.flow_add(
            table_id=test_param_get("table", 0),
            cookie=42,
            match=match,
            instructions=[
                ofp.instruction.apply_actions(
                    actions=[
                        ofp.action.output(port=olt_port)]),
            ],
            buffer_id=ofp.OFP_NO_BUFFER,
            priority=1000)

        self.controller.message_send(request)

        match = ofp.match()
        match.oxm_list.append(ofp.oxm.in_port(olt_port))
        match.oxm_list.append(ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT | vlan_id))

        request = ofp.message.flow_add(
            table_id=test_param_get("table", 0),
            cookie=43,
            match=match,
            instructions=[
                ofp.instruction.apply_actions(
                    actions=[
                        ofp.action.output(port=onu_port)]),
            ],
            buffer_id=ofp.OFP_NO_BUFFER,
            priority=1000)

        self.controller.message_send(request)
        do_barrier(self.controller)
        verify_no_errors(self.controller)

        # It takes some time for flows to propagate down to the data plane
        time.sleep(2)

        inPkt = simple_udp_packet(dl_vlan_enable=True, vlan_vid=vlan_id, vlan_pcp=0)
        # upstream
        self.dataplane.send(onu_port, str(inPkt))
        verify_packet(self, inPkt, olt_port)
        # downstream
        self.dataplane.send(olt_port, str(inPkt))
        verify_packet(self, inPkt, onu_port)

        # clean up the test
        delete_all_flows(self.controller)
        do_barrier(self.controller)
        verify_no_errors(self.controller)

class RemoveRuleTest(base_tests.SimpleDataPlane):

    def runTest(self):
        logging.info("Testing Rule removal")
        processEapolRule(self, onu_port)
        #wait for the rule to settle
        time.sleep(3)

        installDoubleTaggingRule(1, 2, self.controller)
        #wait for the rules to settle
        time.sleep(3)

        stats = get_flow_stats(self, ofp.match())

        test.assertTrue(len(stats) == 3, \
                        "Wrong number of rules reports; reported %s, expected 3\n\n %s" % (len(stats), stats))

        processEapolRule(self, onu_port, install = False)
        time.sleep(3)

        stats = get_flow_stats(self, ofp.match())

        test.assertTrue(len(stats) == 2, \
                        "Wrong number of rules reports; reported %s, expected 2\n\n %s" % (len(stats), stats))

        logging.info(stats)


class MultipleDoubleTaggingForwarding(base_tests.SimpleDataPlane):

    def runTests(self):
        logging.info("Testing multiple Q-in-Q rules")
        pass


class DoubleVlanTest(base_tests.SimpleDataPlane):
    def runTest(self):
        logging.info("Running double vlan tests")
        delete_all_flows(self.controller)

        c_vlan_id = 100
        s_vlan_id = 102
        # upstream flow rule
        installDoubleTaggingRule(s_vlan_id, c_vlan_id, self.controller)

        # It takes some time for flows to propagate down to the data plane
        time.sleep(10)
        testPacketFlow(self, c_vlan_id, s_vlan_id)

        time.sleep(2)

        # clean up the test
        delete_all_flows(self.controller)
        do_barrier(self.controller)
        verify_no_errors(self.controller)


class TestCyclingDoubleVlan(base_tests.SimpleDataPlane):
    """Cycle through vlans and test traffic flow"""

    def runTest(self):
        logging.info("Running cycling vlan test")

        for stag in xrange(2, 4000, 100):
            for ctag in xrange(2, 4000, 100):
                delete_all_flows(self.controller)
                time.sleep(5)
                installDoubleTaggingRule(stag, ctag, self.controller)
                time.sleep(5)
                testPacketFlow(self, ctag, stag)

def processEapolRule(test, in_port, install = True):
    match = ofp.match()
    match.oxm_list.append(ofp.oxm.eth_type(0x888e))
    match.oxm_list.append(ofp.oxm.in_port(in_port))
    if install:
        request = ofp.message.flow_add(
                table_id=test_param_get("table", 0),
                cookie=42,
                match=match,
                instructions=[
                    ofp.instruction.apply_actions(
                        actions=[
                            ofp.action.output(
                                port=ofp.OFPP_CONTROLLER,
                                max_len=ofp.OFPCML_NO_BUFFER)])],
                buffer_id=ofp.OFP_NO_BUFFER,
                priority=1000)
    else:
        request = ofp.message.flow_delete(
                table_id=test_param_get("table", 0),
                cookie=42,
                match=m,
                instructions=[
                    ofp.instruction.apply_actions(
                        actions=[
                            ofp.action.output(
                                port=ofp.OFPP_CONTROLLER,
                                max_len=ofp.OFPCML_NO_BUFFER)])],
                buffer_id=ofp.OFP_NO_BUFFER,
                priority=1000)
    logging.info("%s flow sending matching packets to controller" % "Install" if install else "Remove")
    test.controller.message_send(request)
    do_barrier(test.controller)

def testPacketFlow(test, c_vlan_id, s_vlan_id):

    incorrectTagPkt = simple_udp_packet(pktlen=100, dl_vlan_enable=True, vlan_vid=100, vlan_pcp=0)
    untaggedPkt = simple_udp_packet(pktlen=100, dl_vlan_enable=True, vlan_vid=0, vlan_pcp=0)

    upstreamDoubleTaggedPkt = double_vlan_udp_packet(pktlen=104, dl_vlan_enable=True,
                                                     c_vlan_vid=c_vlan_id,
                                                     s_vlan_vid=s_vlan_id,
                                                     c_vlan_pcp=0, s_vlan_pcp=0)

    logging.info("Testing s-tag %d, c-tag %d" % (s_vlan_id, c_vlan_id))

    test.dataplane.send(onu_port, str(untaggedPkt))
    verify_packet(test, upstreamDoubleTaggedPkt, olt_port)

    # test downstream doubletagged packet got untagged at ONU
    test.dataplane.send(olt_port, str(upstreamDoubleTaggedPkt))
    verify_packet(test, untaggedPkt, onu_port)

    # test upstream doubletagged packet got dropped
    test.dataplane.send(onu_port, str(upstreamDoubleTaggedPkt))
    verify_no_packet(test, upstreamDoubleTaggedPkt, olt_port)

    # test downstream untagged packet got dropped at ONU
    test.dataplane.send(olt_port, str(untaggedPkt))
    verify_no_packet(test, untaggedPkt, onu_port)

    # test upstream icorrectly tagged packet; should get dropped
    test.dataplane.send(onu_port, str(incorrectTagPkt))
    verify_no_packet(test, upstreamDoubleTaggedPkt, olt_port)


def installDoubleTaggingRule(s_vlan_id, c_vlan_id, controller, cookie  = 42):
    # upstream flow rule
    match = ofp.match()
    match.oxm_list.append(ofp.oxm.in_port(onu_port))
    match.oxm_list.append(ofp.oxm.vlan_vid(value=ofp.OFPVID_PRESENT))
    match.oxm_list.append(ofp.oxm.vlan_pcp(value=0))
    cookie += 1

    # push inner vlan (c-vlan) for upstream
    request = ofp.message.flow_add(
        table_id=test_param_get("table", 0),
        cookie=cookie,
        match=match,
        instructions=[
            ofp.instruction.apply_actions(
                actions=[
                    ofp.action.set_field(ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT | c_vlan_id))]),
            ofp.instruction.goto_table(1)],
        buffer_id=ofp.OFP_NO_BUFFER,
        priority=1000)

    controller.message_send(request)
    do_barrier(controller)
    verify_no_errors(controller)

    # push outer vlan (s-vlan) for upstream
    match = ofp.match()
    match.oxm_list.append(ofp.oxm.in_port(onu_port))
    match.oxm_list.append(ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT | c_vlan_id))
    match.oxm_list.append(ofp.oxm.vlan_pcp(0))
    cookie += 1

    request = ofp.message.flow_add(
        table_id=test_param_get("table", 1),
        cookie=cookie,
        match=match,
        instructions=[
            ofp.instruction.apply_actions(
                actions=[
                    ofp.action.push_vlan(ethertype=0x8100),
                    ofp.action.set_field(ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT | s_vlan_id)),
                    ofp.action.set_field(ofp.oxm.vlan_pcp(0)),
                    ofp.action.output(port=olt_port)]),
        ],
        buffer_id=ofp.OFP_NO_BUFFER,
        priority=1000)

    controller.message_send(request)
    do_barrier(controller)
    verify_no_errors(controller)
    cookie += 1

    # strip outer vlan (s-vlan) for downstream
    match = ofp.match()
    match.oxm_list.append(ofp.oxm.in_port(olt_port))
    match.oxm_list.append(ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT | s_vlan_id))
    match.oxm_list.append(ofp.oxm.vlan_pcp(0))
    request = ofp.message.flow_add(
        table_id=test_param_get("table", 0),
        cookie=cookie,
        match=match,
        instructions=[
            ofp.instruction.apply_actions(
                actions=[ofp.action.pop_vlan()]),
            ofp.instruction.goto_table(1)],
        buffer_id=ofp.OFP_NO_BUFFER,
        priority=1000)

    controller.message_send(request)
    do_barrier(controller)
    verify_no_errors(controller)

    # rewrite inner vlan (c-vlan) to default (0) for downstream
    match = ofp.match()
    match.oxm_list.append(ofp.oxm.in_port(olt_port))
    match.oxm_list.append(ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT | c_vlan_id))
    match.oxm_list.append(ofp.oxm.vlan_pcp(0))
    cookie += 1

    request = ofp.message.flow_add(
        table_id=test_param_get("table", 1),
        cookie=cookie,
        match=match,
        instructions=[
            ofp.instruction.apply_actions(
                actions=[
                    ofp.action.pop_vlan(),
                    ofp.action.output(port=onu_port)])
        ],
        buffer_id=ofp.OFP_NO_BUFFER,
        priority=1000)

    controller.message_send(request)
    do_barrier(controller)
    verify_no_errors(controller)



