'''
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 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
        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))

        # push inner vlan (c-vlan) for upstream
        request = ofp.message.flow_add(
            table_id=test_param_get("table", 0),
            cookie=42,
            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)

        self.controller.message_send(request)
        do_barrier(self.controller)
        verify_no_errors(self.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))

        request = ofp.message.flow_add(
            table_id=test_param_get("table", 1),
            cookie=43,
            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)

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

        # 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=44,
            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)

        self.controller.message_send(request)
        do_barrier(self.controller)
        verify_no_errors(self.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))

        request = ofp.message.flow_add(
            table_id=test_param_get("table", 1),
            cookie=45,
            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)

        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)
        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)

        '''
		FIXME: hack because OLT does _not_ tag packets correctly
			it ignores the eth_type in the push_vlan action
			and always slaps on 0x8100 even though the 
			down stream flow must be 0x88a8.
	    '''
        doubleTaggedPkt = 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, eth_type=0x88a8)

        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)

        # test upstream untagged packet got double tag at OLT
        logging.info(str(doubleTaggedPkt))

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

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

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

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

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

        verify_no_packet(self, upstreamDoubleTaggedPkt, olt_port)

        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")
        delete_all_flows(self.controller)
        self.cookie = 42

        self.vlan_pairs = []

        for stag in xrange(2, 4000, 100):
            for ctag in xrange(2, 4000, 100):
                self.installDoubleTaggingRule(stag, ctag)
                self.vlan_pairs.append((stag, ctag))
                time.sleep(1)
                self.testPacketFlow()

    def testPacketFlow(self):
        for (s_vlan_id, c_vlan_id) in self.vlan_pairs:
            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))

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

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

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

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

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

    def installDoubleTaggingRule(self, s_vlan_id, c_vlan_id):
        # 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))
        self.cookie += 1

        # push inner vlan (c-vlan) for upstream
        request = ofp.message.flow_add(
            table_id=test_param_get("table", 0),
            cookie=self.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)

        self.controller.message_send(request)
        do_barrier(self.controller)
        verify_no_errors(self.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))
        self.cookie += 1

        request = ofp.message.flow_add(
            table_id=test_param_get("table", 1),
            cookie=self.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)

        self.controller.message_send(request)
        do_barrier(self.controller)
        verify_no_errors(self.controller)
        self.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=self.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)

        self.controller.message_send(request)
        do_barrier(self.controller)
        verify_no_errors(self.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))
        self.cookie += 1

        request = ofp.message.flow_add(
            table_id=test_param_get("table", 1),
            cookie=self.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)

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