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

import ofp
import time

from oftest.testutils import *

onu_port = test_param_get("onu_port", 1)
onu_port2 = test_param_get("onu_port2", 2)
olt_port = test_param_get("olt_port", 129)

def testPacketIn(self, match, parsed_pkt):

    delete_all_flows(self.controller)

    pkt = str(parsed_pkt)

    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)

    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, [])

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 ARPPacketIn(base_tests.SimpleDataPlane):
    
    """Verify packet-ins are sent for ARP packets """
    
    def runTest(self):
        logging.info("Running ARP Packet In test")

        match = ofp.match()
        match.oxm_list.append(ofp.oxm.eth_type(0x0806))

        # Use ethertype 0x0806
        pkt = simple_eth_packet(eth_type=0x0806)
        
        testPacketIn(self, match, pkt)
        
class DHCPPacketIn(base_tests.SimpleDataPlane):
    
    """Verify packet-ins are sent for DHCP packets """
    
    def runTest(self):
        logging.info("Running DHCP Packet In test")

        pkt = simple_udp_packet(udp_sport=68, udp_dport=67)

        match = ofp.match()
        match.oxm_list.append(ofp.oxm.eth_type(0x0800))
        match.oxm_list.append(ofp.oxm.ip_proto(17))
        match.oxm_list.append(ofp.oxm.udp_src(68))
        match.oxm_list.append(ofp.oxm.udp_dst(67))
        
        testPacketIn(self, match, pkt)
        
        # Other UDP packets should not match the rule
        radiusPkt = simple_udp_packet(udp_sport=1812, udp_dport=1812)

        self.dataplane.send(1, str(radiusPkt))
        verify_no_packet_in(self, radiusPkt, 1)    
        
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 TestMeter(base_tests.SimpleDataPlane):
       
    def runTest(self):
        logging.info("Running Meter tests")
        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)
    
        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
        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.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(2)
        
        inPkt = simple_udp_packet(pktlen=104,dl_vlan_enable=True,
                                  vlan_vid=vlan_id, vlan_pcp=0, dl_vlan_cfi=0)
        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(2)

        self.dataplane.send(olt_port, str(inPkt))
        verify_packet(self, outPkt, onu_port)
        verify_packet(self, outPkt, 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 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)
        # downstream
        self.dataplane.send(olt_port, str(inPkt))
        verify_packet(self, inPkt, onu_port)
        # upstream
        self.dataplane.send(onu_port, str(inPkt))
        verify_packet(self, inPkt, olt_port)
        

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

 
