"""
"""
import struct

import logging

from oftest import config
import oftest.controller as controller
import ofp
import oftest.base_tests as base_tests

from oftest.testutils import *

class bsn_action_mirror(ofp.action.vendor):
    def __init__(self):
        self.type = ofp.OFPAT_VENDOR
        self.len = 24
        self.vendor = 0x005c16c7
        self.subtype = 1
        self.dest_port = 0
        self.vlan_tag = 0
        self.copy_stage = 0

    def __assert(self):
        return (True, None)

    def pack(self, assertstruct=True):
        return struct.pack("!HHLLLLBBBB", self.type, self.len, self.vendor,
                           self.subtype, self.dest_port, self.vlan_tag,
                           self.copy_stage, 0, 0, 0)

    def unpack(self, binaryString):
        if len(binaryString) < self.len:
            raise Exception("too short")
        x = struct.unpack("!HHLLLLBBBB", binaryString[:self.len])
        if x[0] != self.type:
            raise Exception("wrong type")
        if x[1] != self.len:
            raise Exception("wrong length")
        if x[2] != self.vendor:
            raise Exception("wrong vendor")
        if x[3] != self.subtype:
            raise Exception("wrong subtype")
        self.dest_port = x[4]
        self.vlan_tag = x[5]
        self.copy_stage = x[6]
        return binaryString[self.len:]

    def __len__(self):
        return self.len

    def __eq__(self, other):
        if type(self) != type(other): return False
        if self.type != other.type: return False
        if self.len != other.len: return False
        if self.vendor != other.vendor: return False
        if self.subtype != other.subtype: return False
        if self.dest_port != other.dest_port: return False
        if self.vlan_tag != other.vlan_tag: return False
        if self.copy_stage != other.copy_stage: return False
        return True

    def __ne__(self, other):
        return not self.__eq__(other)

    def show(self, prefix=""):
        outstr = prefix + "action_vendor\n"
        for f in ["type", "len", "vendor", "subtype", "dest_port", "vlan_tag",
                  "copy_stage"]:
            outstr += prefix + ("%s: %s\n" % (f, getattr(self, f)))
        return outstr

action_list.action_object_map[ofp.OFPAT_VENDOR] = bsn_action_mirror

@nonstandard
class BSNMirrorAction(base_tests.SimpleDataPlane):
    """
    Exercise BSN vendor extension for copying packets to a mirror destination
    port
    """

    def bsn_set_mirroring(self, enabled):
        """
        Use the BSN_SET_MIRRORING vendor command to enable/disable
        mirror action support
        """
        m = ofp.message.vendor()
        m.vendor = 0x005c16c7
        m.data = struct.pack("!LBBBB", 3, enabled, 0, 0, 0)
        self.controller.message_send(m)

    def bsn_get_mirroring(self):
        """
        Use the BSN_GET_MIRRORING_REQUEST vendor command to get the
        enabled/disabled state of mirror action support
        """
        m = ofp.message.vendor()
        m.vendor = 0x005c16c7
        m.data = struct.pack("!LBBBB", 4, 0, 0, 0, 0)
        self.controller.message_send(m)
        m, r = self.controller.poll(ofp.OFPT_VENDOR, 2)
        self.assertEqual(m.vendor, 0x005c16c7, "Wrong vendor ID")
        x = struct.unpack("!LBBBB", m.data)
        self.assertEqual(x[0], 5, "Wrong subtype")
        return x[1]

    def runTest(self):
        mirror_ports = test_param_get("mirror_ports")
        ports = [p for p in config["port_map"].keys() if p not in mirror_ports]
        pkt = simple_tcp_packet()
        match = packet_to_flow_match(self, pkt)
        match.in_port = ports[0]
        match.wildcards &= ~ofp.OFPFW_IN_PORT

        logging.info("Checking that mirror ports are not reported")
        self.assertEqual(bool(self.bsn_get_mirroring()), False)
        m, r = self.controller.transact(ofp.message.features_request(), 2)
        p = dict([(pt.port_no, pt) for pt in m.ports])
        self.assertFalse(mirror_ports[0] in p or mirror_ports[1] in p,
                         "Mirror port in features reply")

        logging.info("Enabling mirror port reporting")
        self.bsn_set_mirroring(True)

        logging.info("Checking that mirror ports are reported")
        self.assertEqual(bool(self.bsn_get_mirroring()), True)
        m, r = self.controller.transact(ofp.message.features_request(), 2)
        p = dict([(pt.port_no, pt) for pt in m.ports])
        self.assertTrue(mirror_ports[0] in p and mirror_ports[1] in p,
                        "Mirror port not in features reply")
        self.assertTrue(p[mirror_ports[0]].config & (1 << 31),
                        "Mirror port config flag not set in features reply")
        self.assertTrue(p[mirror_ports[1]].config & (1 << 31),
                        "Mirror port config flag not set in features reply")

        act1 = bsn_action_mirror()
        act1.dest_port = mirror_ports[0]
        act1.copy_stage = 0
        act2 = bsn_action_mirror()
        act2.dest_port = mirror_ports[1]
        act2.copy_stage = 0
        act3 = ofp.action.output()
        act3.port = ports[1]
        flow_mod = ofp.message.flow_mod()
        flow_mod.match = match
        flow_mod.actions.append(act1)
        flow_mod.actions.append(act2)
        flow_mod.actions.append(act3)
        delete_all_flows(self.controller)
        self.controller.message_send(flow_mod)
        do_barrier(self.controller)
        
        logging.info("Sending packet to port %s" % ports[0])
        self.dataplane.send(ports[0], str(pkt))
        logging.info("Checking that packet was received from output port %s, "
                     "mirror ports %s and %s" % (
              ports[1], mirror_ports[0], mirror_ports[1]))
        receive_pkt_check(self.dataplane, pkt,
                          [ports[1], mirror_ports[0], mirror_ports[1]], [],
                          self)
