# Copyright 2013, Big Switch Networks, Inc.
#
# LoxiGen is licensed under the Eclipse Public License, version 1.0 (EPL), with
# the following special exception:
#
# LOXI Exception
#
# As a special exception to the terms of the EPL, you may distribute libraries
# generated by LoxiGen (LoxiGen Libraries) under the terms of your choice, provided
# that copyright and licensing notices generated by LoxiGen are not altered or removed
# from the LoxiGen Libraries and the notice provided below is (i) included in
# the LoxiGen Libraries, if distributed in source code form and (ii) included in any
# documentation for the LoxiGen Libraries, if distributed in binary form.
#
# Notice: "Copyright 2013, Big Switch Networks, Inc. This library was generated by the LoxiGen Compiler."
#
# You may not use this file except in compliance with the EPL or LOXI Exception. You may obtain
# a copy of the EPL at:
#
# http://www.eclipse.org/legal/epl-v10.html
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# EPL for the specific language governing permissions and limitations
# under the EPL.

##
# @brief C code generation for LOXI type related maps
#

import c_gen.of_g_legacy as of_g
import sys
from generic_utils import *
import c_gen.type_maps as type_maps


# Some number larger than small type values, but less then
# reserved values like 0xffff
max_type_value = 1000

def gen_object_id_to_type(out):
    out.write("""
/**
 * Map from object ID to primary wire type
 *
 * For messages, this is the header type; in particular for stats, this is
 * the common stats request/response type.  For per-stats types, use the
 * stats type map.  For things like actions, instructions or queue-props,
 * this gives the "sub type".
 */
""")
    for version in of_g.of_version_range:
        out.write("static const int\nof_object_to_type_map_v%d[OF_OBJECT_COUNT] = {\n"
                  %version)
        out.write("    -1, /* of_object, not a valid specific type */\n")
        for j, cls in enumerate(of_g.all_class_order):
            comma = ""
            if j < len(of_g.all_class_order) - 1: # Avoid ultimate comma
                comma = ","

            if cls in type_maps.stats_reply_list:
                out.write("    %d%s /* %s */\n" %
                          (type_maps.type_val[("of_stats_reply", version)],
                           comma, cls))
            elif cls in type_maps.stats_request_list:
                out.write("    %d%s /* %s */\n" %
                          (type_maps.type_val[("of_stats_request", version)],
                           comma, cls))
            elif cls in type_maps.error_msg_list:
                out.write("    %d%s /* %s */\n" %
                          (type_maps.type_val[("of_error_msg", version)],
                           comma, cls))
            elif cls in type_maps.flow_mod_list:
                out.write("    %d%s /* %s */\n" %
                          (type_maps.type_val[("of_flow_mod", version)],
                           comma, cls))
            elif (cls, version) in type_maps.type_val and \
                    type_maps.type_val[(cls, version)] != type_maps.invalid_type:
                out.write("    %d%s /* %s */\n" %
                          (type_maps.type_val[(cls, version)], comma, cls))
            elif type_maps.message_is_extension(cls, version):
                out.write("    %d%s /* %s */\n" %
                          (type_maps.type_val[("of_experimenter", version)],
                           comma, cls))
            elif type_maps.action_is_extension(cls, version):
                out.write("    %d%s /* %s */\n" %
                          (type_maps.type_val[("of_action_experimenter",
                                               version)],
                           comma, cls))
            elif type_maps.action_id_is_extension(cls, version):
                out.write("    %d%s /* %s */\n" %
                          (type_maps.type_val[("of_action_id_experimenter",
                                               version)],
                           comma, cls))
            elif type_maps.instruction_is_extension(cls, version):
                out.write("    %d%s /* %s */\n" %
                          (type_maps.type_val[("of_instruction_experimenter",
                                               version)],
                           comma, cls))
            elif type_maps.queue_prop_is_extension(cls, version):
                out.write("    %d%s /* %s */\n" %
                          (type_maps.type_val[("of_queue_prop_experimenter",
                                               version)],
                           comma, cls))
            elif type_maps.table_feature_prop_is_extension(cls, version):
                out.write("    %d%s /* %s */\n" %
                    (type_maps.type_val[("of_table_feature_prop_experimenter",
                                         version)],
                     comma, cls))
            else:
                out.write("    -1%s /* %s (invalid) */\n" % (comma, cls))
        out.write("};\n\n")

    out.write("""
/**
 * Unified map, indexed by wire version which is 1-based.
 */
const int *const of_object_to_type_map[OF_VERSION_ARRAY_MAX] = {
    NULL,
""")
    for version in of_g.of_version_range:
        out.write("    of_object_to_type_map_v%d,\n" % version)
    out.write("""
};
""")

def gen_object_id_to_extension_data(out):
    out.write("""
/**
 * Extension data.
 * @fixme There must be a better way to represent this data
 */
""")
    for version in of_g.of_version_range:
        out.write("""
static const of_experimenter_data_t
of_object_to_extension_data_v%d[OF_OBJECT_COUNT] = {
""" % version)
        out.write("    {0, 0, 0}, /* of_object, not a valid specific type */\n")
        for j, cls in enumerate(of_g.all_class_order):
            comma = ""
            if j < len(of_g.all_class_order) - 1: # Avoid ultimate comma
                comma = ","

            if type_maps.class_is_extension(cls, version):
                exp_name = type_maps.extension_to_experimenter_macro_name(cls)
                subtype = type_maps.extension_to_subtype(cls, version)
                out.write("    {1, %s, %d}%s /* %s */\n" %
                          (exp_name, subtype, comma, cls))
            else:
                out.write("    {0, 0, 0}%s /* %s (non-extension) */\n" %
                          (comma, cls))
        out.write("};\n\n")

    out.write("""
/**
 * Unified map, indexed by wire version which is 1-based.
 */
const of_experimenter_data_t *const of_object_to_extension_data[OF_VERSION_ARRAY_MAX] = {
    NULL,
""")
    for version in of_g.of_version_range:
        out.write("    of_object_to_extension_data_v%d,\n" % version)
    out.write("""
};
""")

def gen_type_to_object_id(out, type_str, prefix, template,
                          value_array, max_val):
    """
    Generate C maps from various message class groups to object ids

    For each version, create an array mapping the type info to the
    object ID.  Then define an array containing those pointers.
    """

    # Create unified arrays and get length
    arr_len = type_maps.type_array_len(value_array, max_val)
    all_ars = []
    for version, val_dict in value_array.items(): # Per version dict
        ar = type_maps.dict_to_array(val_dict, max_val, type_maps.invalid_type)
        all_ars.append(ar)

    len_name = "%s_ITEM_COUNT" % prefix

    for i, ar in enumerate(all_ars):
        version = i + 1
        out.write("static const of_object_id_t\nof_%s_v%d[%s] = {\n" %
                  (type_str, version, len_name))
        for i in range(arr_len):
            comma = ""
            if i < arr_len - 1: # Avoid ultimate comma
                comma = ","

            # Per-version length check
            if i < len(ar):
                v = ar[i]
            else:
                v = type_maps.invalid_type

            if v == type_maps.invalid_type:
                out.write("    %-30s /* %d (Invalid) */\n" %
                          ("OF_OBJECT_INVALID" + comma, i))
            else:
                name = (template % v.upper()) + comma
                out.write("    %-30s /* %d */\n" % (name, i))
        out.write("};\n")

    out.write("""
/**
 * Maps from %(c_name)s wire type values to LOCI object ids
 *
 * Indexed by wire version which is 1-based.
 */

const of_object_id_t *const of_%(name)s[OF_VERSION_ARRAY_MAX] = {
    NULL,
""" % dict(name=type_str, c_name=prefix.lower()))
    for version in of_g.of_version_range:
        out.write("    of_%(name)s_v%(version)d,\n" % dict(name=type_str,
                                                           version=version))
    out.write("""
};

""" % dict(name=type_str, u_name=type_str.upper(),
           max_val=max_val, c_name=prefix.lower()))

def gen_type_maps(out):
    """
    Generate various type maps
    @param out The file handle to write to
    """

    out.write("#include <loci/loci.h>\n\n")

    # Generate maps from wire type values to object IDs
    gen_type_to_object_id(out, "error_msg_type_to_id", "OF_ERROR_MSG",
                          "OF_%s_ERROR_MSG", type_maps.error_types,
                          max_type_value)
    gen_type_to_object_id(out, "action_type_to_id", "OF_ACTION",
                          "OF_ACTION_%s", type_maps.action_types,
                          max_type_value)
    gen_type_to_object_id(out, "action_id_type_to_id", "OF_ACTION_ID",
                          "OF_ACTION_ID_%s", type_maps.action_id_types,
                          max_type_value)
    gen_type_to_object_id(out, "instruction_type_to_id", "OF_INSTRUCTION",
                          "OF_INSTRUCTION_%s", type_maps.instruction_types,
                          max_type_value)
    gen_type_to_object_id(out, "queue_prop_type_to_id", "OF_QUEUE_PROP",
                          "OF_QUEUE_PROP_%s", type_maps.queue_prop_types,
                          max_type_value)
    gen_type_to_object_id(out, "table_feature_prop_type_to_id",
                          "OF_TABLE_FEATURE_PROP",
                          "OF_TABLE_FEATURE_PROP_%s",
                          type_maps.table_feature_prop_types,
                          max_type_value)
    gen_type_to_object_id(out, "meter_band_type_to_id", "OF_METER_BAND",
                          "OF_METER_BAND_%s", type_maps.meter_band_types,
                          max_type_value)
    gen_type_to_object_id(out, "hello_elem_type_to_id", "OF_HELLO_ELEM",
                          "OF_HELLO_ELEM_%s", type_maps.hello_elem_types,
                          max_type_value)

    # FIXME:  Multipart re-organization
    gen_type_to_object_id(out, "stats_request_type_to_id", "OF_STATS_REQUEST",
                          "OF_%s_STATS_REQUEST", type_maps.stats_types,
                          max_type_value)
    gen_type_to_object_id(out, "stats_reply_type_to_id", "OF_STATS_REPLY",
                          "OF_%s_STATS_REPLY", type_maps.stats_types,
                          max_type_value)
    gen_type_to_object_id(out, "flow_mod_type_to_id", "OF_FLOW_MOD",
                          "OF_FLOW_%s", type_maps.flow_mod_types,
                          max_type_value)
    gen_type_to_object_id(out, "oxm_type_to_id", "OF_OXM",
                          "OF_OXM_%s", type_maps.oxm_types, max_type_value)
    gen_type_to_object_id(out, "message_type_to_id", "OF_MESSAGE",
                          "OF_%s", type_maps.message_types, max_type_value)

    gen_object_id_to_type(out)
    gen_object_id_to_extension_data(out)
    # Don't need array mapping ID to stats types right now; handled directly
    # gen_object_id_to_stats_type(out)


def gen_type_to_obj_map_functions(out):
    """
    Generate the templated static inline type map functions
    @param out The file handle to write to
    """

    ################################################################
    # Generate all type-to-object-ID maps in a common way
    ################################################################
    map_template = """
/**
 * %(name)s wire type to object ID array.
 * Treat as private; use function accessor below
 */

extern const of_object_id_t *const of_%(name)s_type_to_id[OF_VERSION_ARRAY_MAX];

#define OF_%(u_name)s_ITEM_COUNT %(ar_len)d\n

/**
 * Map an %(name)s wire value to an OF object
 * @param %(name)s The %(name)s type wire value
 * @param version The version associated with the check
 * @return The %(name)s OF object type
 * @return OF_OBJECT_INVALID if type does not map to an object
 *
 */
static inline of_object_id_t
of_%(name)s_to_object_id(int %(name)s, of_version_t version)
{
    if (!OF_VERSION_OKAY(version)) {
        return OF_OBJECT_INVALID;
    }
    if (%(name)s < 0 || %(name)s >= OF_%(u_name)s_ITEM_COUNT) {
        return OF_OBJECT_INVALID;
    }

    return of_%(name)s_type_to_id[version][%(name)s];
}
"""
    map_with_experimenter_template = """
/**
 * %(name)s wire type to object ID array.
 * Treat as private; use function accessor below
 */

extern const of_object_id_t *const of_%(name)s_type_to_id[OF_VERSION_ARRAY_MAX];

#define OF_%(u_name)s_ITEM_COUNT %(ar_len)d\n

/**
 * Map an %(name)s wire value to an OF object
 * @param %(name)s The %(name)s type wire value
 * @param version The version associated with the check
 * @return The %(name)s OF object type
 * @return OF_OBJECT_INVALID if type does not map to an object
 *
 */
static inline of_object_id_t
of_%(name)s_to_object_id(int %(name)s, of_version_t version)
{
    if (!OF_VERSION_OKAY(version)) {
        return OF_OBJECT_INVALID;
    }
    if (%(name)s == OF_EXPERIMENTER_TYPE) {
        return OF_%(u_name)s_EXPERIMENTER;
    }
    if (%(name)s < 0 || %(name)s >= OF_%(u_name)s_ITEM_COUNT) {
        return OF_OBJECT_INVALID;
    }

    return of_%(name)s_type_to_id[version][%(name)s];
}
"""

    stats_template = """
/**
 * %(name)s wire type to object ID array.
 * Treat as private; use function accessor below
 */

extern const of_object_id_t *const of_%(name)s_type_to_id[OF_VERSION_ARRAY_MAX];

#define OF_%(u_name)s_ITEM_COUNT %(ar_len)d\n

/**
 * Map an %(name)s wire value to an OF object
 * @param %(name)s The %(name)s type wire value
 * @param version The version associated with the check
 * @return The %(name)s OF object type
 * @return OF_OBJECT_INVALID if type does not map to an object
 *
 */
static inline of_object_id_t
of_%(name)s_to_object_id(int %(name)s, of_version_t version)
{
    if (!OF_VERSION_OKAY(version)) {
        return OF_OBJECT_INVALID;
    }
    if (%(name)s == OF_EXPERIMENTER_TYPE) {
        return OF_EXPERIMENTER_%(u_name)s;
    }
    if (%(name)s < 0 || %(name)s >= OF_%(u_name)s_ITEM_COUNT) {
        return OF_OBJECT_INVALID;
    }

    return of_%(name)s_type_to_id[version][%(name)s];
}
"""

    error_msg_template = """
/**
 * %(name)s wire type to object ID array.
 * Treat as private; use function accessor below
 */

extern const of_object_id_t *const of_%(name)s_type_to_id[OF_VERSION_ARRAY_MAX];

#define OF_%(u_name)s_ITEM_COUNT %(ar_len)d\n

/**
 * Map an %(name)s wire value to an OF object
 * @param %(name)s The %(name)s type wire value
 * @param version The version associated with the check
 * @return The %(name)s OF object type
 * @return OF_OBJECT_INVALID if type does not map to an object
 *
 */
static inline of_object_id_t
of_error_msg_to_object_id(uint16_t %(name)s, of_version_t version)
{
    if (!OF_VERSION_OKAY(version)) {
        return OF_OBJECT_INVALID;
    }
    if (%(name)s == OF_EXPERIMENTER_TYPE) {
        return OF_EXPERIMENTER_ERROR_MSG;
    }
    if (%(name)s < 0 || %(name)s >= OF_%(u_name)s_ITEM_COUNT) {
        return OF_OBJECT_INVALID;
    }

    return of_%(name)s_type_to_id[version][%(name)s];
}
"""

    # Experimenter mapping functions
    # Currently we support very few candidates, so we just do a
    # list of if/elses
    experimenter_function = """
/**
 * @brief Map a message known to be an exp msg to the proper object
 *
 * Assume that the message is a vendor/experimenter message.  Determine
 * the specific object type for the message.
 * @param msg An OF message object (uint8_t *)
 * @param length The number of bytes in the message (for error checking)
 * @param version Version of message
 * @returns object ID of specific type if recognized or OF_EXPERIMENTER if not
 *
 * @todo put OF_EXPERIMENTER_<name> in loci_base.h
 */

static inline of_object_id_t
of_message_experimenter_to_object_id(of_message_t msg, of_version_t version) {
    uint32_t experimenter_id;
    uint32_t subtype;

    /* Extract experimenter and subtype value; look for match from type maps */
    experimenter_id = of_message_experimenter_id_get(msg);
    subtype = of_message_experimenter_subtype_get(msg);

    /* Do a simple if/else search for the ver, experimenter and subtype */
"""
    first = True
    for version, experimenter_lists in type_maps.extension_message_subtype.items():
        for exp, subtypes in experimenter_lists.items():
            experimenter_function += """
    if ((experimenter_id == OF_EXPERIMENTER_ID_%(exp_name)s) &&
            (version == %(ver_name)s)) {
""" % dict(exp_name=exp.upper(), ver_name=of_g.wire_ver_map[version])
            for ext_msg, subtype in subtypes.items():
                experimenter_function += """
        if (subtype == %(subtype)s) {
            return %(ext_msg)s;
        }
""" % dict(subtype=subtype, ext_msg=ext_msg.upper())
            experimenter_function += """
    }
"""
    experimenter_function += """
    return OF_EXPERIMENTER;
}
"""

    # Message need different handling
    msg_template = """
/**
 * %(name)s wire type to object ID array.
 * Treat as private; use function accessor below
 */

extern const of_object_id_t *const of_%(name)s_type_to_id[OF_VERSION_ARRAY_MAX];

#define OF_%(u_name)s_ITEM_COUNT %(ar_len)d\n

/**
 * Extract the type info from the message and determine its object type
 * @param msg An OF message object (uint8_t *)
 * @param length The number of bytes in the message (for error checking)
 * @returns object ID or OF_OBJECT_INVALID if parse error
 */

static inline of_object_id_t
of_message_to_object_id(of_message_t msg, int length) {
    uint8_t type;
    of_version_t ver;
    of_object_id_t obj_id;
    uint16_t stats_type;
    uint16_t err_type;
    uint8_t flow_mod_cmd;
    uint32_t experimenter, subtype;

    if (length < OF_MESSAGE_MIN_LENGTH) {
        return OF_OBJECT_INVALID;
    }
    type = of_message_type_get(msg);
    ver = of_message_version_get(msg);
    if (!OF_VERSION_OKAY(ver)) {
        return OF_OBJECT_INVALID;
    }

    if (type >= OF_MESSAGE_ITEM_COUNT) {
        return OF_OBJECT_INVALID;
    }

    obj_id = of_message_type_to_id[ver][type];

    /* Remap to specific message if known */
    if (obj_id == OF_EXPERIMENTER) {
        if (length < OF_MESSAGE_EXPERIMENTER_MIN_LENGTH) {
            return OF_OBJECT_INVALID;
        }
        return of_message_experimenter_to_object_id(msg, ver);
    }

    /* Remap to add/delete/strict version */
    if (obj_id == OF_FLOW_MOD) {
        if (length < OF_MESSAGE_MIN_FLOW_MOD_LENGTH(ver)) {
            return OF_OBJECT_INVALID;
        }
        flow_mod_cmd = of_message_flow_mod_command_get(msg, ver);
        obj_id = of_flow_mod_to_object_id(flow_mod_cmd, ver);
    }

    if ((obj_id == OF_STATS_REQUEST) || (obj_id == OF_STATS_REPLY)) {
        if (length < OF_MESSAGE_MIN_STATS_LENGTH) {
            return OF_OBJECT_INVALID;
        }
        stats_type = of_message_stats_type_get(msg);
        if (stats_type == OF_STATS_TYPE_EXPERIMENTER) {
            if (length < OF_MESSAGE_STATS_EXPERIMENTER_MIN_LENGTH) {
                return OF_OBJECT_INVALID;
            }
            experimenter = of_message_stats_experimenter_id_get(msg);
            subtype = of_message_stats_experimenter_subtype_get(msg);
            if (obj_id == OF_STATS_REQUEST) {
                obj_id = of_experimenter_stats_request_to_object_id(experimenter, subtype, ver);
            } else {
                obj_id = of_experimenter_stats_reply_to_object_id(experimenter, subtype, ver);
            }
        } else {
            if (obj_id == OF_STATS_REQUEST) {
                obj_id = of_stats_request_to_object_id(stats_type, ver);
            } else {
                obj_id = of_stats_reply_to_object_id(stats_type, ver);
            }
        }
    }

    if (obj_id == OF_ERROR_MSG) {
        if (length < OF_MESSAGE_MIN_ERROR_LENGTH) {
            return OF_OBJECT_INVALID;
        }
        err_type = of_message_error_type_get(msg);
        obj_id = of_error_msg_to_object_id(err_type, ver);
    }

    return obj_id;
}
"""

    oxm_template = """
/**
 * oxm wire type to object ID array.
 * Treat as private; use function accessor below
 */

extern const of_object_id_t *const of_oxm_type_to_id[OF_VERSION_ARRAY_MAX];

#define OF_OXM_ITEM_COUNT %(ar_len)d\n

/**
 * Map an oxm wire value to an OF object
 * @param oxm The oxm type wire value
 * @param version The version associated with the check
 * @return The oxm OF object type
 * @return OF_OBJECT_INVALID if type does not map to an object
 *
 */
static inline of_object_id_t
of_oxm_to_object_id(uint32_t type_len, of_version_t version)
{
    if (!OF_VERSION_OKAY(version)) {
        return OF_OBJECT_INVALID;
    }

    uint16_t class = (type_len >> 16) & 0xffff;
    uint8_t masked_type = (type_len >> 8) & 0xff;

    if (class == 0x8000) {
        if (masked_type < 0 || masked_type >= OF_OXM_ITEM_COUNT) {
            return OF_OBJECT_INVALID;
        }

        return of_oxm_type_to_id[version][masked_type];
    } else if (class == 0x0003) {
        switch (masked_type) {
        case 0x00: return OF_OXM_BSN_IN_PORTS_128;
        case 0x01: return OF_OXM_BSN_IN_PORTS_128_MASKED;
        case 0x02: return OF_OXM_BSN_LAG_ID;
        case 0x03: return OF_OXM_BSN_LAG_ID_MASKED;
        case 0x04: return OF_OXM_BSN_VRF;
        case 0x05: return OF_OXM_BSN_VRF_MASKED;
        case 0x06: return OF_OXM_BSN_GLOBAL_VRF_ALLOWED;
        case 0x07: return OF_OXM_BSN_GLOBAL_VRF_ALLOWED_MASKED;
        case 0x08: return OF_OXM_BSN_L3_INTERFACE_CLASS_ID;
        case 0x09: return OF_OXM_BSN_L3_INTERFACE_CLASS_ID_MASKED;
        case 0x0a: return OF_OXM_BSN_L3_SRC_CLASS_ID;
        case 0x0b: return OF_OXM_BSN_L3_SRC_CLASS_ID_MASKED;
        case 0x0c: return OF_OXM_BSN_L3_DST_CLASS_ID;
        case 0x0d: return OF_OXM_BSN_L3_DST_CLASS_ID_MASKED;
        default: return OF_OBJECT_INVALID;
        }
    } else {
        return OF_OBJECT_INVALID;
    }
}
"""

    # Action types array gen
    ar_len = type_maps.type_array_len(type_maps.action_types, max_type_value)
    out.write(map_with_experimenter_template %
              dict(name="action", u_name="ACTION", ar_len=ar_len))

    # Action ID types array gen
    ar_len = type_maps.type_array_len(type_maps.action_id_types, max_type_value)
    out.write(map_with_experimenter_template %
              dict(name="action_id", u_name="ACTION_ID", ar_len=ar_len))

    # Instruction types array gen
    ar_len = type_maps.type_array_len(type_maps.instruction_types,
                                      max_type_value)
    out.write(map_with_experimenter_template %
              dict(name="instruction", u_name="INSTRUCTION", ar_len=ar_len))

    # Queue prop types array gen
    ar_len = type_maps.type_array_len(type_maps.queue_prop_types,
                                      max_type_value)
    out.write(map_with_experimenter_template %
              dict(name="queue_prop", u_name="QUEUE_PROP", ar_len=ar_len))

    # Table feature prop types array gen
    ar_len = type_maps.type_array_len(type_maps.table_feature_prop_types,
                                      max_type_value)
    out.write(map_with_experimenter_template %
              dict(name="table_feature_prop", u_name="TABLE_FEATURE_PROP",
                   ar_len=ar_len))

    # Meter band types array gen
    ar_len = type_maps.type_array_len(type_maps.meter_band_types,
                                      max_type_value)
    out.write(map_with_experimenter_template %
              dict(name="meter_band", u_name="METER_BAND", ar_len=ar_len))

    # Hello elem types array gen
    ar_len = type_maps.type_array_len(type_maps.hello_elem_types,
                                      max_type_value)
    out.write(map_template %
              dict(name="hello_elem", u_name="HELLO_ELEM", ar_len=ar_len))

    # Stats types array gen
    ar_len = type_maps.type_array_len(type_maps.stats_types,
                                      max_type_value)
    out.write(stats_template %
              dict(name="stats_reply", u_name="STATS_REPLY", ar_len=ar_len))
    out.write(stats_template %
              dict(name="stats_request", u_name="STATS_REQUEST",
                   ar_len=ar_len))

    ar_len = type_maps.type_array_len(type_maps.error_types,
                                      max_type_value)
    out.write(error_msg_template %
              dict(name="error_msg", u_name="ERROR_MSG", ar_len=ar_len))
#     out.write(error_msg_function)

    ar_len = type_maps.type_array_len(type_maps.flow_mod_types, max_type_value)
    out.write(map_template %
              dict(name="flow_mod", u_name="FLOW_MOD", ar_len=ar_len))

    # OXM
    ar_len = type_maps.type_array_len(type_maps.oxm_types, max_type_value)
    out.write("""
/* NOTE: We could optimize the OXM and only generate OF 1.2 versions. */
""")
    out.write(oxm_template % dict(ar_len=ar_len))

    # Messages
    out.write(experimenter_function)
    # Must follow stats reply/request
    ar_len = type_maps.type_array_len(type_maps.message_types, max_type_value)
    out.write(msg_template %
              dict(name="message", u_name="MESSAGE", ar_len=ar_len))

def gen_obj_to_type_map_functions(out):
    """
    Generate the static line maps from object IDs to types
    @param out The file handle to write to
    """

    ################################################################
    # Generate object ID to primary type map
    ################################################################

    out.write("""
extern const int *const of_object_to_type_map[OF_VERSION_ARRAY_MAX];

/**
 * Map an object ID to its primary wire type value
 * @param id An object ID
 * @return For message objects, the type value in the OpenFlow header
 * @return For non-message objects such as actions, instructions, OXMs
 * returns the type value that appears in the respective sub-header
 * @return -1 For improper version or out of bounds input
 *
 * NOTE that for stats request/reply, returns the header type, not the
 * sub-type
 *
 * Also, note that the value is returned as a signed integer.  So -1 is
 * an error code, while 0xffff is the usual "experimenter" code.
 */
static inline int
of_object_to_wire_type(of_object_id_t id, of_version_t version)
{
    if (!OF_VERSION_OKAY(version)) {
        return -1;
    }
    if (id < 0 || id >= OF_OBJECT_COUNT) {
        return -1;
    }
    return of_object_to_type_map[version][id];
}

""")

    # Now for experimenter ids
    out.write("""
/**
 * Map from object ID to a triple, (is_extension, experimenter id, subtype)
 */
""")
    out.write("""
typedef struct of_experimenter_data_s {
    int is_extension;  /* Boolean indication that this is an extension */
    uint32_t experimenter_id;
    uint32_t subtype;
} of_experimenter_data_t;

""")

    out.write("""
extern const of_experimenter_data_t *const of_object_to_extension_data[OF_VERSION_ARRAY_MAX];

/**
 * Map from the object ID of an extension to the experimenter ID
 */
static inline uint32_t
of_extension_to_experimenter_id(of_object_id_t obj_id, of_version_t ver)
{
    if (obj_id < 0 || obj_id > OF_OBJECT_COUNT) {
        return (uint32_t) -1;
    }
    /* @fixme: Verify ver? */
    return of_object_to_extension_data[ver][obj_id].experimenter_id;
}

/**
 * Map from the object ID of an extension to the experimenter subtype
 */
static inline uint32_t
of_extension_to_experimenter_subtype(of_object_id_t obj_id, of_version_t ver)
{
    if (obj_id < 0 || obj_id > OF_OBJECT_COUNT) {
        return (uint32_t) -1;
    }
    /* @fixme: Verify ver? */
    return of_object_to_extension_data[ver][obj_id].subtype;
}

/**
 * Boolean function indicating the the given object ID/version
 * is recognized as a supported (decode-able) extension.
 */
static inline int
of_object_id_is_extension(of_object_id_t obj_id, of_version_t ver)
{
    if (obj_id < 0 || obj_id > OF_OBJECT_COUNT) {
        return (uint32_t) -1;
    }
    /* @fixme: Verify ver? */
    return of_object_to_extension_data[ver][obj_id].is_extension;
}
""")

    ################################################################
    # Generate object ID to the stats sub-type map
    ################################################################

    out.write("""
/**
 * Map an object ID to a stats type
 * @param id An object ID
 * @return The wire value for the stats type
 * @return -1 if not supported for this version
 * @return -1 if id is not a specific stats type ID
 *
 * Note that the value is returned as a signed integer.  So -1 is
 * an error code, while 0xffff is the usual "experimenter" code.
 */

static inline int
of_object_to_stats_type(of_object_id_t id, of_version_t version)
{
    if (!OF_VERSION_OKAY(version)) {
        return -1;
    }
    switch (id) {
""")
    # Assumes 1.2 contains all stats types and type values are
    # the same across all versions
    stats_names = dict()
    for ver in of_g.of_version_range:
        for name, value in type_maps.stats_types[ver].items():
            if name in stats_names and (not value == stats_names[name]):
                print "ERROR stats type differ violating assumption"
                sys.exit(1)
            stats_names[name] = value

    for name, value in stats_names.items():
        out.write("    case OF_%s_STATS_REPLY:\n" % name.upper())
        out.write("    case OF_%s_STATS_REQUEST:\n" % name.upper())
        for version in of_g.of_version_range:
            if not name in type_maps.stats_types[version]:
                out.write("        if (version == %s) break;\n" %
                          of_g.of_version_wire2name[version])
        out.write("        return %d;\n" % value)
    out.write("""
    default:
        break;
    }
    return -1; /* Not recognized as stats type object for this version */
}
""")

    ################################################################
    # Generate object ID to the error sub-type map
    ################################################################
    out.write("""
/**
 * Map an object ID to an error type
 * @param id An object ID
 * @return The wire value for the error type
 * @return -1 if not supported for this version
 * @return -1 if id is not a specific error type ID
 *
 * Note that the value is returned as a signed integer.  So -1 is
 * an error code, while 0xffff is the usual "experimenter" code.
 */

static inline int
of_object_to_error_type(of_object_id_t id, of_version_t version)
{
    if (!OF_VERSION_OKAY(version)) {
        return -1;
    }
    switch (id) {""")
    error_names = set()
    for ver in of_g.of_version_range:
        for name in type_maps.error_types[ver]:
            error_names.add(name)
    for name in error_names:
        out.write("""
    case OF_%(name)s_ERROR_MSG:
        if (OF_ERROR_TYPE_%(name)s_SUPPORTED(version))
            return OF_ERROR_TYPE_%(name)s_BY_VERSION(version);
        break;""" % {"name": name.upper()})
    out.write("""
    default:
        break;
    }
    return -1; /* Not recognized as error type object for this version */
}
""")

    ################################################################
    # Generate object ID to the flow mod sub-type map
    ################################################################

    out.write("""
/**
 * Map an object ID to a flow-mod command value
 * @param id An object ID
 * @return The wire value for the flow-mod command
 * @return -1 if not supported for this version
 * @return -1 if id is not a specific stats type ID
 *
 * Note that the value is returned as a signed integer.  So -1 is
 * an error code, while 0xffff is the usual "experimenter" code.
 */

static inline int
of_object_to_flow_mod_command(of_object_id_t id, of_version_t version)
{
    if (!OF_VERSION_OKAY(version)) {
        return -1;
    }
    switch (id) {
""")
    # Assumes 1.2 contains all stats types and type values are
    # the same across all versions
    flow_mod_names = dict()
    for ver in of_g.of_version_range:
        for name, value in type_maps.flow_mod_types[ver].items():
            if name in flow_mod_names and \
                    (not value == flow_mod_names[name]):
                print "ERROR flow mod command differ violating assumption"
                sys.exit(1)
            flow_mod_names[name] = value

    for name, value in flow_mod_names.items():
        out.write("    case OF_FLOW_%s:\n" % name.upper())
        for version in of_g.of_version_range:
            if not name in type_maps.flow_mod_types[version]:
                out.write("        if (version == %s) break;\n" %
                          of_g.of_version_wire2name[version])
        out.write("        return %d;\n" % value)
    out.write("""
    default:
        break;
    }
    return -1; /* Not recognized as flow mod type object for this version */
}

""")

def gen_type_maps_header(out):
    """
    Generate various header file declarations for type maps
    @param out The file handle to write to
    """

    out.write("""
/**
 * Generic experimenter type value.  Applies to all except
 * top level message: Action, instruction, error, stats, queue_props, oxm
 */
#define OF_EXPERIMENTER_TYPE 0xffff

int of_experimenter_stats_request_to_object_id(uint32_t experimenter, uint32_t subtype, int ver);
int of_experimenter_stats_reply_to_object_id(uint32_t experimenter, uint32_t subtype, int ver);
""")
    gen_type_to_obj_map_functions(out)
    gen_obj_to_type_map_functions(out)

    out.write("extern const int *const of_object_fixed_len[OF_VERSION_ARRAY_MAX];\n")
    out.write("extern const int *const of_object_extra_len[OF_VERSION_ARRAY_MAX];\n")

    out.write("""
/**
 * Map a message in a wire buffer object to its OF object id.
 * @param wbuf Pointer to a wire buffer object, populated with an OF message
 * @returns The object ID of the message
 * @returns OF_OBJECT_INVALID if unable to parse the message type
 */

static inline of_object_id_t
of_wire_object_id_get(of_wire_buffer_t *wbuf)
{
    of_message_t msg;

    msg = (of_message_t)WBUF_BUF(wbuf);
    return of_message_to_object_id(msg, WBUF_CURRENT_BYTES(wbuf));
}

/**
 * Use the type/length from the wire buffer and init the object
 * @param obj The object being initialized
 * @param base_object_id If > 0, this indicates the base object
 * @param max_len If > 0, the max length to expect for the obj
 * type for inheritance checking
 * @return OF_ERROR_
 *
 * Used for inheritance type objects such as actions and OXMs
 * The type is checked and if valid, the object is initialized.
 * Then the length is taken from the buffer.
 *
 * Note that the object version must already be properly set.
 */
static inline int
of_object_wire_init(of_object_t *obj, of_object_id_t base_object_id,
                    int max_len)
{
    if (obj->wire_type_get != NULL) {
        of_object_id_t id;
        obj->wire_type_get(obj, &id);
        if (!of_wire_id_valid(id, base_object_id)) {
            return OF_ERROR_PARSE;
        }
        obj->object_id = id;
        /* Call the init function for this object type; do not push to wire */
        of_object_init_map[id]((of_object_t *)(obj), obj->version, -1, 0);
    }
    if (obj->wire_length_get != NULL) {
        int length;
        obj->wire_length_get(obj, &length);
        if (length < 0 || (max_len > 0 && length > max_len)) {
            return OF_ERROR_PARSE;
        }
        obj->length = length;
    } else {
        /* @fixme Does this cover everything else? */
        obj->length = of_object_fixed_len[obj->version][base_object_id];
    }

    return OF_ERROR_NONE;
}

""")

    # Generate the function that sets the object type fields
    out.write("""

/**
 * Map a message in a wire buffer object to its OF object id.
 * @param wbuf Pointer to a wire buffer object, populated with an OF message
 * @returns The object ID of the message
 * @returns OF_OBJECT_INVALID if unable to parse the message type
 *
 * Version must be set in the buffer prior to calling this routine
 */

static inline int
of_wire_message_object_id_set(of_wire_buffer_t *wbuf, of_object_id_t id)
{
    int type;
    of_version_t ver;
    of_message_t msg;

    msg = (of_message_t)WBUF_BUF(wbuf);

    ver = of_message_version_get(msg);

    /* ASSERT(id is a message object) */

    if ((type = of_object_to_wire_type(id, ver)) < 0) {
        return OF_ERROR_PARAM;
    }
    of_message_type_set(msg, type);

    if ((type = of_object_to_stats_type(id, ver)) >= 0) {
        /* It's a stats obj */
        of_message_stats_type_set(msg, type);
        if (type == OF_STATS_TYPE_EXPERIMENTER) {
            switch (id) {
            case OF_BSN_LACP_STATS_REQUEST:
            case OF_BSN_LACP_STATS_REPLY:
                of_message_stats_experimenter_id_set(msg, OF_EXPERIMENTER_ID_BSN);
                of_message_stats_experimenter_subtype_set(msg, 1);
                break;
            case OF_BSN_SWITCH_PIPELINE_STATS_REQUEST:
            case OF_BSN_SWITCH_PIPELINE_STATS_REPLY:
                of_message_stats_experimenter_id_set(msg, OF_EXPERIMENTER_ID_BSN);
                of_message_stats_experimenter_subtype_set(msg, 6);
                break;
            default:
                break;
            }
        }
    }
    if ((type = of_object_to_error_type(id, ver)) >= 0) {
        /* It's an error obj */
        of_message_error_type_set(msg, type);
    }
    if ((type = of_object_to_flow_mod_command(id, ver)) >= 0) {
        /* It's a flow mod obj */
        of_message_flow_mod_command_set(msg, ver, type);
    }
    if (of_object_id_is_extension(id, ver)) {
        uint32_t val32;

        /* Set the experimenter and subtype codes */
        val32 = of_extension_to_experimenter_id(id, ver);
        of_message_experimenter_id_set(msg, val32);
        val32 = of_extension_to_experimenter_subtype(id, ver);
        of_message_experimenter_subtype_set(msg, val32);
    }

    return OF_ERROR_NONE;
}
""")

def gen_type_data_header(out):

    out.write("""
/****************************************************************
 *
 * The following declarations are for type and length calculations.
 * Implementations may be found in of_type_maps.c
 *
 ****************************************************************/
/*
 * Special case length functions for objects with
 */
""")
    for ((cls, name), prev) in of_g.special_offsets.items():
        s_cls = cls[3:] # take off of_
        out.write("""
/**
 * Special length calculation for %(cls)s->%(name)s.
 * @param obj An object of type %(cls)s to check for
 * length of %(name)s
 * @param bytes[out] Where to store the calculated length
 *
 * Preceding data member is %(prev)s.
 */
extern int of_length_%(s_cls)s_%(name)s_get(
    %(cls)s_t *obj, int *bytes);

/**
 * Special offset calculation for %(cls)s->%(name)s.
 * @param obj An object of type %(cls)s to check for
 * length of %(name)s
 * @param offset[out] Where to store the calculated length
 *
 * Preceding data member is %(prev)s.
 */
extern int of_offset_%(s_cls)s_%(name)s_get(
    %(cls)s_t *obj, int *offset);
""" % dict(cls=cls, s_cls=s_cls, name=name, prev=prev))

# NOT NEEDED YET
#     # For non-message, variable length objects, give a fun that
#     # calculates the length
#     for cls in of_g.standard_class_order:
#         s_cls = cls[3:] # take off of_
#         if !type_is_var_len(cls, version):
#             continue
#         out.write("""
# /**
#  * Special length calculation for variable length object %(cls)s
#  * @param obj An object of type %(cls)s whose length is being calculated
#  * @param bytes[out] Where to store the calculated length
#  *
#  * The assumption is that the length member of the object is not
#  * valid and the length needs to be calculated from other information
#  * such as the parent.
#  */
# extern int of_length_%(s_cls)s_get(
#     %(cls)s_t *obj, int *bytes);
# """ % dict(cls=cls, s_cls=s_cls))

    out.write("""
/****************************************************************
 * Wire type/length functions.
 ****************************************************************/

extern void of_object_message_wire_length_get(of_object_t *obj, int *bytes);
extern void of_object_message_wire_length_set(of_object_t *obj, int bytes);

extern void of_oxm_wire_length_get(of_object_t *obj, int *bytes);
extern void of_oxm_wire_length_set(of_object_t *obj, int bytes);
extern void of_oxm_wire_object_id_get(of_object_t *obj, of_object_id_t *id);
extern void of_oxm_wire_object_id_set(of_object_t *obj, of_object_id_t id);

extern void of_tlv16_wire_length_get(of_object_t *obj, int *bytes);
extern void of_tlv16_wire_length_set(of_object_t *obj, int bytes);

extern void of_tlv16_wire_object_id_set(of_object_t *obj, of_object_id_t id);

/* Wire length is uint16 at front of structure */
extern void of_u16_len_wire_length_get(of_object_t *obj, int *bytes);
extern void of_u16_len_wire_length_set(of_object_t *obj, int bytes);

extern void of_action_wire_object_id_get(of_object_t *obj, of_object_id_t *id);
extern void of_action_id_wire_object_id_get(of_object_t *obj, of_object_id_t *id);
extern void of_instruction_wire_object_id_get(of_object_t *obj,
    of_object_id_t *id);
extern void of_queue_prop_wire_object_id_get(of_object_t *obj,
    of_object_id_t *id);
extern void of_table_feature_prop_wire_object_id_get(of_object_t *obj,
    of_object_id_t *id);
extern void of_meter_band_wire_object_id_get(of_object_t *obj,
    of_object_id_t *id);
extern void of_hello_elem_wire_object_id_get(of_object_t *obj,
    of_object_id_t *id);

#define OF_OXM_LENGTH_GET(hdr) (((hdr) & 0xff) + 4)
#define OF_OXM_LENGTH_SET(hdr, val)                         \\
    (hdr) = ((hdr) & 0xffffff00) + (((val) - 4) & 0xff)

extern void of_packet_queue_wire_length_get(of_object_t *obj, int *bytes);
extern void of_packet_queue_wire_length_set(of_object_t *obj, int bytes);

extern void of_list_meter_band_stats_wire_length_get(of_object_t *obj,
                                                    int *bytes);
extern void of_meter_stats_wire_length_get(of_object_t *obj, int *bytes);
extern void of_meter_stats_wire_length_set(of_object_t *obj, int bytes);
extern int of_extension_object_wire_push(of_object_t *obj);

""")


def gen_length_array(out):
    """
    Generate an array giving the lengths of all objects/versions
    @param out The file handle to which to write
    """
    out.write("""
/**
 * An array with the number of bytes in the fixed length part
 * of each OF object
 */
""")

    for version in of_g.of_version_range:
        out.write("""
static const int\nof_object_fixed_len_v%d[OF_OBJECT_COUNT] = {
    -1,   /* of_object is not instantiable */
""" % version)
        for i, cls in enumerate(of_g.all_class_order):
            comma = ","
            if i == len(of_g.all_class_order) - 1:
                comma = ""
            val = "-1" + comma
            if (cls, version) in of_g.base_length:
                val = str(of_g.base_length[(cls, version)]) + comma
            out.write("    %-5s /* %d: %s */\n" % (val, i + 1, cls))
        out.write("};\n")

    out.write("""
/**
 * Unified map of fixed length part of each object
 */
const int *const of_object_fixed_len[OF_VERSION_ARRAY_MAX] = {
    NULL,
""")
    for version in of_g.of_version_range:
        out.write("    of_object_fixed_len_v%d,\n" % version)
    out.write("""
};
""")


def gen_extra_length_array(out):
    """
    Generate an array giving the extra lengths of all objects/versions
    @param out The file handle to which to write
    """
    out.write("""
/**
 * An array with the number of bytes in the extra length part
 * of each OF object
 */
""")

    for version in of_g.of_version_range:
        out.write("""
static const int\nof_object_extra_len_v%d[OF_OBJECT_COUNT] = {
    -1,   /* of_object is not instantiable */
""" % version)
        for i, cls in enumerate(of_g.all_class_order):
            comma = ","
            if i == len(of_g.all_class_order) - 1:
                comma = ""
            val = "-1" + comma
            if (cls, version) in of_g.base_length:
                val = str(of_g.extra_length.get((cls, version), 0)) + comma
            out.write("    %-5s /* %d: %s */\n" % (val, i + 1, cls))
        out.write("};\n")

    out.write("""
/**
 * Unified map of extra length part of each object
 */
const int *const of_object_extra_len[OF_VERSION_ARRAY_MAX] = {
    NULL,
""")
    for version in of_g.of_version_range:
        out.write("    of_object_extra_len_v%d,\n" % version)
    out.write("""
};
""")


################################################################
################################################################

# THIS IS PROBABLY NOT NEEDED AND MAY NOT BE CALLED CURRENTLY
def gen_object_id_to_stats_type(out):
    out.write("""
/**
 * Map from message object ID to stats type
 *
 * All message object IDs are mapped for simplicity
 */
""")
    for version in of_g.of_version_range:
        out.write("const int *of_object_to_stats_type_map_v%d = {\n" % (i+1))
        out.write("    -1, /* of_object (invalid) */\n");
        for cls in of_g.ordered_messages:
            name = cls[3:]
            name = name[:name.find("_stats")]
            if (((cls in type_maps.stats_reply_list) or
                 (cls in type_maps.stats_request_list)) and
                name in type_maps.stats_types[i]):
                out.write("    %d, /* %s */\n" %
                          (type_maps.stats_types[i][name], cls))
            else:
                out.write("    -1, /* %s (invalid) */\n" % cls)
        out.write("};\n\n")

    out.write("""
/**
 * Unified map, indexed by wire version which is 1-based.
 */
const int *of_object_to_stats_type_map[OF_VERSION_ARRAY_MAX] = {
    NULL,
""")
    for version in of_g.of_version_range:
        out.write("    of_object_to_stats_type_map_v%d,\n" % version)
    out.write("""
};
""")

