
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:
        st_hdr = ofp_stats_request()
        st_hdr.unpack(binary_string)
        return stats_request_to_class_map[st_hdr.type]()
    elif hdr.type == OFPT_STATS_REPLY:
        st_hdr = ofp_stats_reply()
        st_hdr.unpack(binary_string)
        return stats_reply_to_class_map[st_hdr.type]()
    elif hdr.type == OFPT_STATS_REPLY:
        st_hdr = ofp_error_msg()
        st_hdr.unpack(binary_string)
        return error_to_class_map[st_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

