o
from message import *
from error import *
from action import *
from action_list import action_list
from ofp import *

"""
of_message.py
Contains wrapper functions and classes for the of_message namespace
that are generated by hand.  It includes the rest of the wrapper
function information into the of_message namespace
"""

# These message types are subclassed
msg_type_subclassed = [
    OFPT_STATS_REQUEST,
    OFPT_STATS_REPLY,
    OFPT_ERROR
]

# Maps from sub-types to classes
stats_reply_to_class_map = {
    OFPST_DESC                      : desc_stats_reply,
    OFPST_AGGREGATE                 : aggregate_stats_reply,
    OFPST_FLOW                      : flow_stats_reply,
    OFPST_TABLE                     : table_stats_reply,
    OFPST_PORT                      : port_stats_reply,
    OFPST_QUEUE                     : queue_stats_reply
}

stats_request_to_class_map = {
    OFPST_DESC                      : desc_stats_request,
    OFPST_AGGREGATE                 : aggregate_stats_request,
    OFPST_FLOW                      : flow_stats_request,
    OFPST_TABLE                     : table_stats_request,
    OFPST_PORT                      : port_stats_request,
    OFPST_QUEUE                     : queue_stats_request
}

error_to_class_map = {
    OFPET_HELLO_FAILED              : hello_failed_error_msg,
    OFPET_BAD_REQUEST               : bad_request_error_msg,
    OFPET_BAD_ACTION                : bad_action_error_msg,
    OFPET_FLOW_MOD_FAILED           : flow_mod_failed_error_msg,
    OFPET_PORT_MOD_FAILED           : port_mod_failed_error_msg,
    OFPET_QUEUE_OP_FAILED           : queue_op_failed_error_msg
}

# Map from header type value to the underlieing message class
msg_type_to_class_map = {
    OFPT_HELLO                      : hello,
    OFPT_ERROR                      : error,
    OFPT_ECHO_REQUEST               : echo_request,
    OFPT_ECHO_REPLY                 : echo_reply,
    OFPT_VENDOR                     : vendor,
    OFPT_FEATURES_REQUEST           : features_request,
    OFPT_FEATURES_REPLY             : features_reply,
    OFPT_GET_CONFIG_REQUEST         : get_config_request,
    OFPT_GET_CONFIG_REPLY           : get_config_reply,
    OFPT_SET_CONFIG                 : set_config,
    OFPT_PACKET_IN                  : packet_in,
    OFPT_FLOW_REMOVED               : flow_removed,
    OFPT_PORT_STATUS                : port_status,
    OFPT_PACKET_OUT                 : packet_out,
    OFPT_FLOW_MOD                   : flow_mod,
    OFPT_PORT_MOD                   : port_mod,
    OFPT_STATS_REQUEST              : stats_request,
    OFPT_STATS_REPLY                : stats_reply,
    OFPT_BARRIER_REQUEST            : barrier_request,
    OFPT_BARRIER_REPLY              : barrier_reply,
    OFPT_QUEUE_GET_CONFIG_REQUEST   : queue_get_config_request,
    OFPT_QUEUE_GET_CONFIG_REPLY     : queue_get_config_reply
}

def _of_message_to_object(binary_string):
    """
    Map a binary string to the corresponding class.

    Appropriately resolves subclasses
    """
    hdr = ofp_header()
    hdr.unpack(binary_string)
    # FIXME: Add error detection
    if not hdr.type in msg_type_subclassed:
        return msg_type_to_class_map[hdr.type]()
    if hdr.type == OFPT_STATS_REQUEST:
        sub_hdr = ofp_stats_request()
        sub_hdr.unpack(binary_string)
        return stats_request_to_class_map[sub_hdr.type]()
    elif hdr.type == OFPT_STATS_REPLY:
        sub_hdr = ofp_stats_reply()
        sub_hdr.unpack(binary_string)
        return stats_reply_to_class_map[sub_hdr.type]()
    elif hdr.type == OFPT_ERROR:
        sub_hdr = ofp_error_msg()
        sub_hdr.unpack(binary_string)
        return error_to_class_map[sub_hdr.type]()
    else:
        print "ERROR parsing packet to object"
        return None

def of_message_parse(binary_string, raw=False):
    """
    Parse an OpenFlow packet

    Parses a raw OpenFlow packet into a Python class, with class
    members fully populated.

    @param binary_string The packet (string) to be parsed
    @param raw If true, interpret the packet as an L2 packet.  Not
    yet supported.
    @return An object of some message class or None if fails

    """

    if raw:
        print "raw packet message parsing not supported"
        return None

    obj = _of_message_to_object(binary_string)
    if obj != None:
        obj.unpack(binary_string)
    return obj


def of_header_parse(binary_string, raw=False):
    """
    Parse only the header from an OpenFlow packet

    Parses the header from a raw OpenFlow packet into a
    an ofp_header Python class.

    @param binary_string The packet (string) to be parsed
    @param raw If true, interpret the packet as an L2 packet.  Not
    yet supported.
    @return An ofp_header object

    """

    if raw:
        print "raw packet message parsing not supported"
        return None

    hdr = ofp_header()
    hdr.unpack(binary_string)

    return hdr

def packet_to_flow(packet, wildcards=None, pkt_format="L2"):
    """
    Create a flow that matches packet with the given wildcards

    @param packet The packet to use as a flow template
    @param wildcards Wildcards to place in the flow (ignore those 
    fields from the packet)
    @param pkt_format May be one string from: L2, L3,  ?  
    Fields from unspecified layers are forced to be wildcards

    """

