# 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.

"""
@file code_gen.py
Code generation functions for LOCI
"""

import sys
import c_gen.of_g_legacy as of_g
import c_match
from generic_utils import *
from c_gen import flags, type_maps, c_type_maps
import c_gen.loxi_utils_legacy as loxi_utils
import loxi_globals

import c_gen.identifiers as identifiers

# 'property' is for queues. Could be trouble

################################################################
#
# Misc helper functions
#
################################################################

def h_file_to_define(name):
    """
    Convert a .h file name to the define used for the header
    """
    h_name = name[:-2].upper()
    h_name = "_" + h_name + "_H_"
    return h_name

def enum_name(cls):
    """
    Return the name used for an enum identifier for the given class
    @param cls The class name
    """
    return loxi_utils.enum_name(cls)

# TODO serialize match outside accessor?
def accessor_return_type(a_type, m_type):
    if loxi_utils.accessor_returns_error(a_type, m_type):
        return "int WARN_UNUSED_RESULT"
    else:
        return "void"

def accessor_return_success(a_type, m_type):
    if loxi_utils.accessor_returns_error(a_type, m_type):
        return "OF_ERROR_NONE"
    else:
        return ""

################################################################
#
# Per-file generators, mapped to jump table below
#
################################################################

def base_h_gen(out, name):
    """
    Generate code for base header file
    @param out The file handle to write to
    @param name The name of the file
    """
    common_top_matter(out, name)
    base_h_content(out)
    gen_object_enum(out)
    out.write("""
/****************************************************************
 *
 * Experimenter IDs
 *
 ****************************************************************/

""")
    for name, val in of_g.experimenter_name_to_id.items():
        out.write("#define OF_EXPERIMENTER_ID_%s 0x%08x\n" %
                  (name.upper(), val))

    out.write("""
/****************************************************************
 *
 * OpenFlow Match version specific and generic defines
 *
 ****************************************************************/
""")
    c_match.gen_v4_match_compat(out)
    c_match.gen_match_macros(out)
    c_match.gen_oxm_defines(out)
    out.write("\n#endif /* Base header file */\n")

def identifiers_gen(out, filename):
    """
    Generate the macros for LOCI identifiers
    @param out The file handle to write to
    @param filename The name of the file
    """
    common_top_matter(out, filename)
    out.write("""
/**
 * For each identifier from an OpenFlow header file, a Loxi version
 * of the identifier is generated.  For example, ofp_port_flood becomes
 * OF_PORT_DEST_FLOOD.  Loxi provides the following macros related to
 * OpenFlow identifiers (using OF_IDENT_ as an example below):
 *     OF_IDENT_BY_VERSION(version) Get the value for the specific version
 *     OF_IDENT_SUPPORTED(version) Boolean: Is OF_IDENT defined for version
 *     OF_IDENT The common value across all versions if defined
 *     OF_IDENT_GENERIC A unique value across all OF identifiers
 *
 * For identifiers marked as flags, the following are also defined
 *     OF_IDENT_SET(flags, version)
 *     OF_IDENT_CLEAR(flags, version)
 *     OF_IDENT_TEST(flags, version)
 *
 * Notes:
 *
 *     OF_IDENT_BY_VERSION(version) returns an undefined value
 * if the passed version does not define OF_IDENT.  It does not generate an
 * error, nor record anything to the log file.  If the value is the same
 * across all defined versions, the version is ignored.
 *
 *     OF_IDENT is only defined if the value is the same across all
 * target LOXI versions FOR WHICH IT IS DEFINED.  No error checking is
 * done.  This allows code to be written without requiring the version
 * to be known or referenced when it doesn't matter.  It does mean
 * that when porting to a new version of OpenFlow, compile errors may
 * occur.  However, this is an indication that the existing code must
 * be updated to account for a change in the semantics with the newly
 * supported OpenFlow version.
 *
 * @fixme Currently we do not handle multi-bit flags or field values; for
 * example, OF_TABLE_CONFIG_TABLE_MISS_CONTROLLER is the meaning for
 * a zero value in the bits indicated by OF_TABLE_CONFIG_TABLE_MISS_MASK.
 *
 * @fixme Need to decide (or make a code gen option) on the requirement
 * for defining OF_IDENT:  Is it that all target versions define it and
 * the agree?  Or only that the versions which define it agree?
 */
""")

    # Build value-by-version parameters and c_code
    if len(of_g.target_version_list) > 1: # Supporting more than one version
        vbv_params = []
        vbv_code = ""
        first = True
        for version in of_g.target_version_list:
            vbv_params.append("value_%s" % of_g.short_version_names[version])
            if not first:
                vbv_code += "\\\n     "
            else:
                first = False
            last_value = "value_%s" % of_g.short_version_names[version]
            vbv_code += "((version) == %s) ? (%s) : " % \
                (of_g.of_version_wire2name[version], last_value)
        # @todo Using last value, can optimize out last ?
        vbv_code += "(%s)" % last_value

    out.write("""
/**
 * @brief True for the special case of all versions supported
 */
#define OF_IDENT_IN_ALL_VERSIONS 1 /* Indicates identifier in all versions */

/**
 * @brief General macro to map version to value where values given as params
 *
 * If unknown version is passed, use the latest version's value
 */
#define OF_VALUE_BY_VERSION(version, %s) \\
    (%s)

/**
 * @brief Generic set a flag
 */
#define OF_FLAG_SET(flags, mask) (flags) = (flags) | (mask)

/**
 * @brief Generic test if a flag is set
 */
#define OF_FLAG_CLEAR(flags, mask) (flags) = (flags) & ~(mask)

/**
 * @brief Generic test if a flag is set
 */
#define OF_FLAG_TEST(flags, mask) ((flags) & (mask) ? 1 : 0)

/**
 * @brief Set a flag where the value is an enum indication of bit shift
 */
#define OF_FLAG_ENUM_SET(flags, e_val) OF_FLAG_SET(flags, 1 << (e_val))

/**
 * @brief Clear a flag where the value is an enum indication of bit shift
 */
#define OF_FLAG_ENUM_CLEAR(flags, e_val) OF_FLAG_CLEAR(flags, 1 << (e_val))

/**
 * @brief Test a flag where the value is an enum indication of bit shift
 */
#define OF_FLAG_ENUM_TEST(flags, e_val) OF_FLAG_TEST(flags, 1 << (e_val))
""" % (", ".join(vbv_params), vbv_code))

    # For each group of identifiers, bunch ident defns
    count = 1
    keys = of_g.identifiers_by_group.keys()
    keys.sort()
    for group in keys:
        idents = of_g.identifiers_by_group[group]
        idents.sort()
        out.write("""
/****************************************************************
 * Identifiers from %s
 *****************************************************************/
""" % group)
        for ident in idents:
            info = of_g.identifiers[ident]

            keys = info["values_by_version"].keys()
            keys.sort()

            out.write("""
/*
 * Defines for %(ident)s
 * Original name %(ofp_name)s
 */
""" % dict(ident=ident, ofp_name=info["ofp_name"]))

            # Generate supported versions macro
            if len(keys) == len(of_g.target_version_list): # Defined for all
                out.write("""\
#define %(ident)s_SUPPORTED(version) OF_IDENT_IN_ALL_VERSIONS
""" % dict(ident=ident))
            else: # Undefined for some version
                sup_list = []
                for version in keys:
                    sup_list.append("((version) == %s)" %
                                    of_g.of_version_wire2name[version])
                out.write("""\
#define %(ident)s_SUPPORTED(version)      \\
    (%(sup_str)s)
""" % dict(ident=ident, sup_str=" || \\\n     ".join(sup_list)))

            # Generate value macro
            if identifiers.defined_versions_agree(of_g.identifiers,
                                                  of_g.target_version_list,
                                                  ident):
                out.write("""\
#define %(ident)s (%(value)#x)
#define %(ident)s_BY_VERSION(version) (%(value)#x)
""" % dict(ident=ident,value=info["common_value"]))
            else: # Values differ between versions
                # Generate version check and value by version
                val_list = []
                # Order of params matters
                for version in of_g.target_version_list:
                    if version in info["values_by_version"]:
                        value = info["values_by_version"][version]
                    else:
                        value = identifiers.UNDEFINED_IDENT_VALUE
                    val_list.append("%#x" % value)
                out.write("""\
#define %(ident)s_BY_VERSION(version)     \\
    OF_VALUE_BY_VERSION(version, %(val_str)s)
""" % dict(ident=ident, val_str=", ".join(val_list)))
            if flags.ident_is_flag(ident):
                log("Treating %s as a flag" % ident)
                out.write("""
#define %(ident)s_SET(flags, version)     \\
    OF_FLAG_SET(flags, %(ident)s_BY_VERSION(version))
#define %(ident)s_TEST(flags, version)    \\
    OF_FLAG_TEST(flags, %(ident)s_BY_VERSION(version))
#define %(ident)s_CLEAR(flags, version)   \\
    OF_FLAG_CLEAR(flags, %(ident)s_BY_VERSION(version))
""" % dict(ident=ident))

            out.write("#define %(ident)s_GENERIC %(count)d\n"
                      % dict(ident=ident, count=count))
            count += 1 # This count should probably be promoted higher

    log("Generated %d identifiers" % (count - 1))
    out.write("\n#endif /* Loci identifiers header file */\n")

def base_h_external(out, filename):
    """
    Copy contents of external file to base header

    The contents of the filename are copied literally into the
    out file handler.  This allows openflow common defines to
    be entered into the LoxiGen code base.  The content of this
    code must depend only on standard C headers.
    """
    infile = open(filename, "r")
    contents = infile.read()
    out.write(contents)
    infile.close()

def match_h_gen(out, name):
    """
    Generate code for
    @param out The file handle to write to
    @param name The name of the file
    """
    c_match.match_h_top_matter(out, name)
    c_match.gen_incompat_members(out)
    c_match.gen_match_struct(out)
    c_match.gen_match_comp(out)
#    c_match.gen_match_accessors(out)
    out.write("\n#endif /* Match header file */\n")

def top_h_gen(out, name):
    """
    Generate code for
    @param out The file handle to write to
    @param name The name of the file
    """
    external_h_top_matter(out, name)
    out.write("""

typedef enum loci_log_level {
    LOCI_LOG_LEVEL_TRACE,
    LOCI_LOG_LEVEL_VERBOSE,
    LOCI_LOG_LEVEL_INFO,
    LOCI_LOG_LEVEL_WARN,
    LOCI_LOG_LEVEL_ERROR,
    LOCI_LOG_LEVEL_MSG
} loci_log_level_t;

/**
 * @brief Output a log message.
 * @param level The log level.
 * @param fname The function name.
 * @param file The file name.
 * @param line The line number.
 * @param format The message format string.
 */
typedef int (*loci_logger_f)(loci_log_level_t level,
                             const char *fname, const char *file, int line,
                             const char *format, ...);

/*
 * This variable should be set by the user of the library to redirect logs to
 * their log infrastructure. The default drops all logs.
 */
extern loci_logger_f loci_logger;

/**
 * Map a generic object to the underlying wire buffer
 *
 * Treat as private
 */
#define OF_OBJECT_TO_MESSAGE(obj) \\
    ((of_message_t)(WBUF_BUF((obj)->wire_object.wbuf)))

/**
 * Macro for the fixed length part of an object
 *
 * @param obj The object whose extended length is being calculated
 * @returns length in bytes of non-variable part of the object
 */
#define OF_OBJECT_FIXED_LENGTH(obj) \\
    (of_object_fixed_len[(obj)->version][(obj)->object_id])

/**
 * Return the length of the object beyond its fixed length
 *
 * @param obj The object whose extended length is being calculated
 * @returns length in bytes of non-variable part of the object
 *
 * Most variable length fields are alone at the end of a structure.
 * Their length is a simple calculation, just the total length of
 * the parent minus the length of the non-variable part of the
 * parent's class type.
 */

#define OF_OBJECT_VARIABLE_LENGTH(obj) \\
    ((obj)->length - OF_OBJECT_FIXED_LENGTH(obj))

/* FIXME: Where do these go? */
/* Low level maps btwn wire version + type and object ids */
extern int of_message_is_stats_request(int type, int w_ver);
extern int of_message_is_stats_reply(int type, int w_ver);
extern int of_message_stats_reply_to_object_id(int stats_type, int w_ver);
extern int of_message_stats_request_to_object_id(int stats_type, int w_ver);
extern int of_message_type_to_object_id(int type, int w_ver);

extern int of_wire_buffer_of_match_get(of_object_t *obj, int offset,
                                    of_match_t *match);
extern int of_wire_buffer_of_match_set(of_object_t *obj, int offset,
                                    of_match_t *match, int cur_len);
""")

    # gen_base_types(out)

    gen_flow_add_setup_function_declarations(out)
    out.write("""
/****************************************************************
 *
 * Declarations of maps between on-the-wire type values and LOCI identifiers
 *
 ****************************************************************/

/**
 * 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);

of_object_id_t of_action_to_object_id(int action, of_version_t version);
of_object_id_t of_action_id_to_object_id(int action_id, of_version_t version);
of_object_id_t of_instruction_to_object_id(int instruction, of_version_t version);
of_object_id_t of_queue_prop_to_object_id(int queue_prop, of_version_t version);
of_object_id_t of_table_feature_prop_to_object_id(int table_feature_prop, of_version_t version);
of_object_id_t of_meter_band_to_object_id(int meter_band, of_version_t version);
of_object_id_t of_hello_elem_to_object_id(int hello_elem, of_version_t version);
of_object_id_t of_stats_reply_to_object_id(int stats_reply, of_version_t version);
of_object_id_t of_stats_request_to_object_id(int stats_request, of_version_t version);
of_object_id_t of_error_msg_to_object_id(uint16_t error_msg, of_version_t version);
of_object_id_t of_flow_mod_to_object_id(int flow_mod, of_version_t version);
of_object_id_t of_group_mod_to_object_id(int group_mod, of_version_t version);
of_object_id_t of_oxm_to_object_id(uint32_t type_len, of_version_t version);
of_object_id_t of_message_experimenter_to_object_id(of_message_t msg, of_version_t version);
of_object_id_t of_message_to_object_id(of_message_t msg, int length);

int of_object_wire_init(of_object_t *obj, of_object_id_t base_object_id, int max_len);

extern const int *const of_object_fixed_len[OF_VERSION_ARRAY_MAX];
extern const int *const of_object_extra_len[OF_VERSION_ARRAY_MAX];
""")
    c_type_maps.gen_type_data_header(out)
    c_match.gen_declarations(out)
    # @fixme Move debug stuff to own fn
    out.write("""
/**
 * Macro to check consistency of length for top level objects
 *
 * If the object has no parent then its length should match the
 * underlying wire buffer's current bytes.
 */
#define OF_LENGTH_CHECK_ASSERT(obj) \\
    ASSERT(((obj)->parent != NULL) || \\
     ((obj)->wire_object.wbuf == NULL) || \\
     (WBUF_CURRENT_BYTES((obj)->wire_object.wbuf) == (obj)->length))

#define OF_DEBUG_DUMP
#if defined(OF_DEBUG_DUMP)
extern void dump_match(of_match_t *match);
#endif /* OF_DEBUG_DUMP */
""")

    out.write("\n#endif /* Top header file */\n")

def match_c_gen(out, name):
    """
    Generate code for
    @param out The file handle to write to
    @param name The name of the file
    """
    c_match.match_c_top_matter(out, name)
    c_match.gen_match_conversions(out)
    c_match.gen_serialize(out)
    c_match.gen_deserialize(out)

################################################################
# Top Matter
################################################################

def common_top_matter(out, name):
    loxi_utils.gen_c_copy_license(out)
    out.write("""\

/****************************************************************
 * File: %s
 *
 * DO NOT EDIT
 *
 * This file is automatically generated
 *
 ****************************************************************/

""" % name)

    if name[-2:] == ".h":
        out.write("""
#if !defined(%(h)s)
#define %(h)s

""" % dict(h=h_file_to_define(name)))

def base_h_content(out):
    """
    Generate base header file content

    @param out The output file object
    """

    # @fixme Supported version should be generated based on input to LoxiGen

    out.write("""
/*
 * Base OpenFlow definitions.  These depend only on standard C headers
 */
#include <string.h>
#include <stdint.h>

/* g++ requires this to pick up PRI, etc.
 * See  http://gcc.gnu.org/ml/gcc-help/2006-10/msg00223.html
 */
#if !defined(__STDC_FORMAT_MACROS)
#define __STDC_FORMAT_MACROS
#endif
#include <inttypes.h>

#include <stdlib.h>
#include <assert.h>
#include <loci/loci_idents.h>

/**
 * Macro to enable debugging for LOCI.
 *
 * This enables debug output to stdout.
 */
#define OF_DEBUG_ENABLE

#if defined(OF_DEBUG_ENABLE)
#include <stdio.h> /* Currently for debugging */
#define FIXME(str) do {                 \\
        fprintf(stderr, "%s\\n", str);  \\
        exit(1);                        \\
    } while (0)
#define debug printf
#else
#define FIXME(str)
#define debug(str, ...)
#endif /* OF_DEBUG_ENABLE */

/**
 * The type of a function used by the LOCI dump/show functions to
 * output text. Essentially the same signature as fprintf. May
 * be called many times per invocation of e.g. of_object_show().
 */
typedef int (*loci_writer_f)(void *cookie, const char *fmt, ...);

/**
 * Check if a version is supported
 */
#define OF_VERSION_OKAY(v) ((v) >= OF_VERSION_1_0 && (v) <= OF_VERSION_1_3)

""")
    gen_version_enum(out)
    out.write("\n")

    # for c_name in of_g.ofp_constants:
    #     val = str(of_g.ofp_constants[c_name])
    #     out.write("#define %s %s\n" % (c_name, val))
    # out.write("\n")

    out.write("""
typedef enum of_error_codes_e {
    OF_ERROR_NONE        = 0,
    OF_ERROR_RESOURCE    = -1,    /* Could not allocate space */
    OF_ERROR_PARAM       = -2,    /* Bad parameter */
    OF_ERROR_VERSION     = -3,    /* Version not supported */
    OF_ERROR_RANGE       = -4,    /* End of list indication */
    OF_ERROR_COMPAT      = -5,    /* Incompatible assignment */
    OF_ERROR_PARSE       = -6,    /* Error in parsing data */
    OF_ERROR_INIT        = -7,    /* Uninitialized data */
    OF_ERROR_UNKNOWN     = -8     /* Unknown error */
} of_error_codes_t;

#define OF_ERROR_STRINGS "none", \\
    "resource", \\
    "parameter", \\
    "version", \\
    "range", \\
    "incompatible", \\
    "parse", \\
    "init", \\
    "unknown"

extern const char *const of_error_strings[];

#ifndef NDEBUG
/* #define ASSERT(val) assert(val) */
#define FORCE_FAULT *(volatile int *)0 = 1
#define ASSERT(val) if (!(val)) \\
    fprintf(stderr, "\\nASSERT %s. %s:%d\\n", #val, __FILE__, __LINE__), \\
    FORCE_FAULT
#else
#define ASSERT(val)
#endif

/*
 * Some LOCI object accessors can fail, and it's easy to forget to check.
 * On certain compilers we can trigger a warning if the error code
 * is ignored.
 */
#ifndef DISABLE_WARN_UNUSED_RESULT
#ifdef __GNUC__
#define WARN_UNUSED_RESULT __attribute__ ((warn_unused_result))
#else
#define WARN_UNUSED_RESULT
#endif
#else
#define WARN_UNUSED_RESULT
#endif

typedef union of_generic_u of_generic_t;
typedef struct of_object_s of_object_t;

/* Define ipv4 address as uint32 */
typedef uint32_t of_ipv4_t;

/* Table ID is the OF standard uint8 */
typedef uint8_t of_table_id_t;

#define OF_MAC_ADDR_BYTES 6
typedef struct of_mac_addr_s {
   uint8_t addr[OF_MAC_ADDR_BYTES];
} of_mac_addr_t;

#define OF_IPV6_BYTES 16
typedef struct of_ipv6_s {
   uint8_t addr[OF_IPV6_BYTES];
} of_ipv6_t;

extern const of_mac_addr_t of_mac_addr_all_ones;
extern const of_mac_addr_t of_mac_addr_all_zeros;

extern const of_ipv6_t of_ipv6_all_ones;
extern const of_ipv6_t of_ipv6_all_zeros;

/**
 * Generic zero and all-ones values of size 16 bytes.
 *
 * IPv6 is longest data type we worry about for comparisons
 */
#define of_all_zero_value of_ipv6_all_zeros
#define of_all_ones_value of_ipv6_all_ones

/**
 * Non-zero/all ones check for arbitrary type of size <= 16 bytes
 */
#define OF_VARIABLE_IS_NON_ZERO(_ptr) \\
    (MEMCMP(&of_all_zero_value, (_ptr), sizeof(*(_ptr))))
#define OF_VARIABLE_IS_ALL_ONES(_ptr) \\
    (!MEMCMP(&of_all_ones_value, (_ptr), sizeof(*(_ptr))))

/* The octets object is a struct holding pointer and length */
typedef struct of_octets_s {
    uint8_t *data;
    int bytes;
} of_octets_t;

/* Macro to convert an octet object to a pointer; currently trivial */
#define OF_OCTETS_POINTER_GET(octet_ptr) ((octet_ptr)->data)
#define OF_OCTETS_POINTER_SET(octet_ptr, ptr) (octet_ptr)->data = (ptr)
#define OF_OCTETS_BYTES_GET(octet_ptr) ((octet_ptr)->bytes)
#define OF_OCTETS_BYTES_SET(octet_ptr, bytes) (octet_ptr)->bytes = (bytes)

/* Currently these are categorized as scalars */
typedef char of_port_name_t[OF_MAX_PORT_NAME_LEN];
typedef char of_table_name_t[OF_MAX_TABLE_NAME_LEN];
typedef char of_desc_str_t[OF_DESC_STR_LEN];
typedef char of_serial_num_t[OF_SERIAL_NUM_LEN];

typedef struct of_bitmap_128_s {
    uint64_t hi;
    uint64_t lo;
} of_bitmap_128_t;

/* These are types which change across versions.  */
typedef uint32_t of_port_no_t;
typedef uint16_t of_fm_cmd_t;
typedef uint64_t of_wc_bmap_t;
typedef uint64_t of_match_bmap_t;

#define MEMMOVE(dest, src, bytes) memmove(dest, src, bytes)
#define MEMSET(dest, val, bytes) memset(dest, val, bytes)
#define MEMCPY(dest, src, bytes) memcpy(dest, src, bytes)
#define MEMCMP(a, b, bytes) memcmp(a, b, bytes)
#define MALLOC(bytes) malloc(bytes)
#define FREE(ptr) free(ptr)

/** Try an operation and return on failure. */
#define OF_TRY(op) do {                                                      \\
        int _rv;                                                             \\
        if ((_rv = (op)) < 0) {                                              \\
            LOCI_LOG_ERROR("ERROR %d at %s:%d\\n", _rv, __FILE__, __LINE__); \\
            return _rv;                                                      \\
        }                                                                    \\
    } while (0)

/* The extent of an OF match object is determined by its length field, but
 * aligned to 8 bytes
 */

#define OF_MATCH_BYTES(length) (((length) + 7) & 0xfff8)

#if __BYTE_ORDER == __BIG_ENDIAN
#define U16_NTOH(val) (val)
#define U32_NTOH(val) (val)
#define U64_NTOH(val) (val)
#define IPV6_NTOH(dst, src) /* NOTE different syntax; currently no-op */
#define U16_HTON(val) (val)
#define U32_HTON(val) (val)
#define U64_HTON(val) (val)
#define IPV6_HTON(dst, src) /* NOTE different syntax; currently no-op */
#else /* Little Endian */
#define U16_NTOH(val) (((val) >> 8) | ((val) << 8))
#define U32_NTOH(val) ((((val) & 0xff000000) >> 24) |                   \\
                       (((val) & 0x00ff0000) >>  8) |                   \\
                       (((val) & 0x0000ff00) <<  8) |                   \\
                       (((val) & 0x000000ff) << 24))
#define U64_NTOH(val) ((((val) & 0xff00000000000000LL) >> 56) |         \\
                       (((val) & 0x00ff000000000000LL) >> 40) |         \\
                       (((val) & 0x0000ff0000000000LL) >> 24) |         \\
                       (((val) & 0x000000ff00000000LL) >>  8) |         \\
                       (((val) & 0x00000000ff000000LL) <<  8) |         \\
                       (((val) & 0x0000000000ff0000LL) << 24) |         \\
                       (((val) & 0x000000000000ff00LL) << 40) |         \\
                       (((val) & 0x00000000000000ffLL) << 56))
#define IPV6_NTOH(dst, src) /* NOTE different syntax; currently no-op */
#define U16_HTON(val) U16_NTOH(val)
#define U32_HTON(val) U32_NTOH(val)
#define U64_HTON(val) U64_NTOH(val)
#define IPV6_HTON(dst, src) /* NOTE different syntax; currently no-op */
#endif

/****************************************************************
 *
 * The following are internal definitions used by the automatically
 * generated code.  Users should not reference these definitions
 * as they may change between versions of this code
 *
 ****************************************************************/

#define OF_MESSAGE_IN_MATCH_POINTER(obj)                            \\
    (WIRE_BUF_POINTER(&((obj)->wire_buffer), OF_MESSAGE_IN_MATCH_OFFSET))
#define OF_MESSAGE_IN_MATCH_LEN(ptr) BUF_U16_GET(&ptr[2])
#define OF_MESSAGE_IN_DATA_OFFSET(obj) \\
    (FIXED_LEN + OF_MESSAGE_IN_MATCH_LEN(OF_MESSAGE_IN_MATCH_POINTER(obj)) + 2)

#define OF_MESSAGE_OUT_DATA_OFFSET(obj) \\
    (FIXED_LEN + of_message_out_actions_len_get(obj))

""")

def external_h_top_matter(out, name):
    """
    Generate top matter for external header file

    @param name The name of the output file
    @param out The output file object
    """
    common_top_matter(out, name)
    out.write("""
#include <loci/loci_base.h>
#include <loci/of_message.h>
#include <loci/of_match.h>
#include <loci/of_object.h>
#include <loci/loci_classes.h>

/****************************************************************
 *
 * This file is divided into the following sections.
 *
 * A few object specific macros
 * Class typedefs (no struct definitions)
 * Per-data type accessor function typedefs
 * Per-class new/delete function typedefs
 * Per-class static delete functions
 * Per-class, per-member accessor declarations
 * Per-class structure definitions
 * Generic union (inheritance) definitions
 * Pointer set function declarations
 * Some special case macros
 *
 ****************************************************************/
""")

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

def gen_version_enum(out):
    """
    Generate the enumerated type for versions in LoxiGen
    @param out The file object to which to write the decs

    This just uses the wire versions for now
    """
    out.write("""
/**
 * Enumeration of OpenFlow versions
 *
 * The wire protocol numbers are currently used for values of the corresponding
 * version identifiers.
 */
typedef enum of_version_e {
    OF_VERSION_UNKNOWN = 0,
""")

    is_first = True
    max = 0
    for v in of_g.wire_ver_map:
        if is_first:
            is_first = False
        else:
            out.write(",\n")
        if v > max:
            max = v
        out.write("    %s = %d" % (of_g.wire_ver_map[v], v))

    out.write("""
} of_version_t;

/**
 * @brief Use this when declaring arrays indexed by wire version
 */
#define OF_VERSION_ARRAY_MAX %d
""" % (max + 1))

def gen_object_enum(out):
    """
    Generate the enumerated type for object identification in LoxiGen
    @param out The file object to which to write the decs
    """
    out.write("""

/**
 * Enumeration of OpenFlow objects
 *
 * We enumerate the OpenFlow objects used internally.  Note that some
 * message types are determined both by an outer type (message type like
 * stats_request) and an inner type (port stats).  These are different
 * messages in ofC.
 *
 * These values are for internal use only.  They will change with
 * different versions of ofC.
 */

typedef enum of_object_id_e {
    /* Root object type */
    OF_OBJECT_INVALID = -1, /* "invalid" return value for mappings */
    OF_OBJECT = 0, /* Generic, untyped object */

    /* OpenFlow message objects */
""")
    last = 0
    msg_count = 0
    for cls in of_g.ordered_messages:
        out.write("    %s = %d,\n" % (enum_name(cls),
                                   of_g.unified[cls]["object_id"]))
        msg_count = of_g.unified[cls]["object_id"] + 1

    out.write("\n    /* Non-message objects */\n")
    for cls in of_g.ordered_non_messages:
        out.write("    %s = %d,\n" % (enum_name(cls),
                                   of_g.unified[cls]["object_id"]))
        last = of_g.unified[cls]["object_id"]
    out.write("\n    /* List objects */\n")
    for cls in of_g.ordered_list_objects:
        out.write("    %s = %d,\n" % (enum_name(cls),
                                   of_g.unified[cls]["object_id"]))
        last = of_g.unified[cls]["object_id"]

    out.write("\n    /* Generic stats request/reply types; pseudo objects */\n")
    for cls in of_g.ordered_pseudo_objects:
        out.write("    %s = %d,\n" % (enum_name(cls),
                                   of_g.unified[cls]["object_id"]))
        last = of_g.unified[cls]["object_id"]

    out.write("""
    OF_OBJECT_COUNT = %d
} of_object_id_t;

extern const char *const of_object_id_str[];

#define OF_MESSAGE_OBJECT_COUNT %d
""" % ((last + 1), msg_count))

    # Generate object type range checking for inheritance classes

    # @fixme These should be determined algorithmicly
    out.write("""
/*
 * Macros to check if an object ID is within an inheritance class range
 */
""")
    # Alphabetical order for 'last'
    last_ids = dict(of_action="OF_ACTION_STRIP_VLAN",
                    of_oxm="OF_OXM_VLAN_VID_MASKED",
                    of_instruction="OF_INSTRUCTION_WRITE_METADATA",
                    of_queue_prop="OF_QUEUE_PROP_MIN_RATE",
                    of_table_feature_prop="OF_TABLE_FEATURE_PROP_WRITE_SETFIELD_MISS",
                    # @FIXME add meter_band ?
                    )
    for cls, last in last_ids.items():
        out.write("""
#define %(enum)s_FIRST_ID      (%(enum)s + 1)
#define %(enum)s_LAST_ID       %(last)s
#define %(enum)s_VALID_ID(id) \\
    ((id) >= %(enum)s_FIRST_ID && \\
     (id) <= %(enum)s_LAST_ID)
""" % dict(enum=enum_name(cls), last=last))
    out.write("""
/**
 * Function to check a wire ID
 * @param object_id The ID to check
 * @param base_object_id The inheritance parent, if applicable
 * @returns boolean: If base_object_id is an inheritance class, check if
 * object_id is valid as a subclass.  Otherwise return 1.
 *
 * Note: Could check that object_id == base_object_id in the
 * second case.
 */
static inline int
of_wire_id_valid(int object_id, int base_object_id) {
    switch (base_object_id) {
    case OF_ACTION:
        return OF_ACTION_VALID_ID(object_id);
    case OF_OXM:
        return OF_OXM_VALID_ID(object_id);
    case OF_QUEUE_PROP:
        return OF_QUEUE_PROP_VALID_ID(object_id);
    case OF_TABLE_FEATURE_PROP:
        return OF_TABLE_FEATURE_PROP_VALID_ID(object_id);
    case OF_INSTRUCTION:
        return OF_INSTRUCTION_VALID_ID(object_id);
    default:
        break;
    }
    return 1;
}
""")

################################################################
#
# Internal Utility Functions
#
################################################################


def acc_name(cls, m_name):
    """
    Generate the root name of an accessor function for typedef
    @param cls The class name
    @param m_name The member name
    """
    (m_type, get_rv) = get_acc_rv(cls, m_name)
    return "%s_%s" % (cls, m_type)

def get_acc_rv(cls, m_name):
    """
    Determine the data type and return type for a get accessor.

    The return type may be "void" or it may be the accessor type
    depending on the system configuration and on the data type.

    @param cls The class name
    @param m_name The member name
    @return A pair (m_type, rv) where m_type is the unified type of the
    member and rv is the get_accessor return type
    """
    member = of_g.unified[cls]["union"][m_name]
    m_type = member["m_type"]
    rv = "int"
    if m_type[-2:] == "_t":
        m_type = m_type[:-2]

    return (m_type, rv)

def param_list(cls, m_name, a_type):
    """
    Generate the parameter list (no parens) for an a_type accessor
    @param cls The class name
    @param m_name The member name
    @param a_type One of "set" or "get" or TBD
    """
    member = of_g.unified[cls]["union"][m_name]
    m_type = member["m_type"]
    params = ["%s_t *obj" % cls]
    if a_type == "set":
        if loxi_utils.type_is_scalar(m_type):
            params.append("%s %s" % (m_type, m_name))
        else:
            params.append("%s *%s" % (m_type, m_name))
    elif a_type in ["get", "bind"]:
        params.append("%s *%s" % (m_type, m_name))
    else:
        debug("Class %s, name %s Bad param list a_type: %s" %
            (cls, m_name, a_type))
        sys.exit(1)
    return params

def typed_function_base(cls, m_name):
    """
    Generate the core name for accessors based on the type
    @param cls The class name
    @param m_name The member name
    """
    (m_type, get_rv) = get_acc_rv(cls, m_name)
    return "%s_%s" % (cls, m_type)

def member_function_base(cls, m_name):
    """
    Generate the core name for accessors based on the member name
    @param cls The class name
    @param m_name The member name
    """
    return "%s_%s" % (cls, m_name)

def field_ver_get(cls, m_name):
    """
    Generate a dict, indexed by wire version, giving a pair (type, offset)

    @param cls The class name
    @param m_name The name of the class member

    If offset is not known for m_name, the type
    A dict is used for more convenient indexing.
    """
    result = {}

    for ver in of_g.unified[cls]:
        if type(ver) == type(0): # It's a version
            if "use_version" in of_g.unified[cls][ver]: # deref version ref
                ref_ver = of_g.unified[cls][ver]["use_version"]
                members = of_g.unified[cls][ref_ver]["members"]
            else:
                members = of_g.unified[cls][ver]["members"]
            idx = loxi_utils.member_to_index(m_name, members)
            if (idx < 0):
                continue # Member not in this version
            m_type = members[idx]["m_type"]
            offset = members[idx]["offset"]

            # If m_type is mixed, get wire version type from global data
            if m_type in of_g.of_mixed_types and \
                    ver in of_g.of_mixed_types[m_type]:
                m_type = of_g.of_mixed_types[m_type][ver]

            # add version to result list
            result[ver] = (m_type, offset)

    return result

def v3_match_offset_get(cls):
    """
    Return the offset of an OF 1.2 match in an object if it has such;
    otherwise return -1
    """
    result = field_ver_get(cls, "match")
    if of_g.VERSION_1_2 in result:
        if result[of_g.VERSION_1_2][0] == "of_match_v3_t":
            return result[of_g.VERSION_1_2][1]
    return -1

################################################################
#
# OpenFlow Object Definitions
#
################################################################


def gen_of_object_defs(out):
    """
    Generate low level of_object core operations
    @param out The file for output, already open
    """

def gen_generics(out):
    for (cls, subclasses) in type_maps.inheritance_map.items():
        out.write("""
/**
 * Inheritance super class for %(cls)s
 *
 * This class is the union of %(cls)s classes.  You can refer
 * to it untyped by refering to the member 'header' whose structure
 * is common across all sub-classes.
 */

union %(cls)s_u {
    %(cls)s_header_t header; /* Generic instance */
""" % dict(cls=cls))
        for subcls in sorted(subclasses):
            out.write("    %s_%s_t %s;\n" % (cls, subcls, subcls))
        out.write("};\n")

def gen_struct_typedefs(out):
    """
    Generate typedefs for all struct objects
    @param out The file for output, already open
    """

    out.write("\n/* LOCI inheritance parent typedefs */\n")
    for cls in type_maps.inheritance_map:
        out.write("typedef union %(cls)s_u %(cls)s_t;\n" % dict(cls=cls))
    out.write("\n/* LOCI object typedefs */\n")
    for cls in of_g.standard_class_order:
        if cls in type_maps.inheritance_map:
            continue
        template = "typedef of_object_t %(cls)s_t;\n"
        out.write(template % dict(cls=cls))

    out.write("""
/****************************************************************
 *
 * Additional of_object defines
 * These are needed for some static inline ops, so we put them here.
 *
 ****************************************************************/

/* Delete an OpenFlow object without reference to its type */
extern void of_object_delete(of_object_t *obj);

""")

def gen_flow_add_setup_function_declarations(out):
    """
    Add the declarations for functions that can be initialized
    by a flow add.  These are defined external to LOXI.
    """

    out.write("""
/****************************************************************
 * Functions for objects that can be initialized by a flow add message.
 * These are defined in a non-autogenerated file
 ****************************************************************/

/**
 * @brief Set up a flow removed message from the original add
 * @param obj The flow removed message being updated
 * @param flow_add The flow_add message to use
 *
 * Initialize the following fields of obj to be identical
 * to what was originally on the wire from the flow_add object:
 *     match
 *     cookie
 *     priority
 *     idle_timeout
 *     hard_timeout
 *
 */

extern int
of_flow_removed_setup_from_flow_add(of_flow_removed_t *obj,
                                    of_flow_add_t *flow_add);


/**
 * @brief Set up the packet in match structure from the original add
 * @param obj The packet in message being updated
 * @param flow_add The flow_add message to use
 * @returns Indigo error code.  Does not return a version error if
 * the version does not require initializing obj.
 *
 * Initialize the match member of obj to be identical to what was originally
 * on the wire from the flow_add object.  If applicable, the table ID is also
 * initialized from the flow_add object.
 *
 * This API applies to 1.2 and later only.
 */

extern int
of_packet_in_setup_from_flow_add(of_packet_in_t *obj,
                                 of_flow_add_t *flow_add);


/**
 * @brief Set up the flow stats entry from the original add
 * @param obj The packet in message being updated
 * @param flow_add The flow_add message to use
 * @param effects Optional actions or instructions; see below.
 *
 * Initialize the following fields of obj to be identical
 * to what was originally on the wire from the flow_add object:
 *     match
 *     actions/instructions (effects)
 *     cookie
 *     priority
 *     idle_timeout
 *     hard_timeout
 *
 * Note that the actions/instructions of a flow may be modified by a
 * subsequent flow modify message.  To facilitate implementations,
 * the "effects" parameter is provided.  If effects is NULL, the
 * actions/instructions are taken from the flow_add message.
 * Otherwise, effects is coerced to the proper type (actions or
 * instructions) and used to init obj.
 */

extern int
of_flow_stats_entry_setup_from_flow_add(of_flow_stats_entry_t *obj,
                                        of_flow_add_t *flow_add,
                                        of_object_t *effects);
""")

################################################################
#
# List accessor code generation
#
# Currently these all implement copy on read semantics
#
################################################################

def init_call(e_type, obj, ver, length, cw):
    """
    Generate the init call given the strings for params
    """
    hdr = "" # If inheritance type, coerce to hdr object
    obj_name = obj
    if e_type in type_maps.inheritance_map:
        hdr = "_header"
        obj_name = "(%s_header_t *)" % e_type + obj

    return """\
%(e_type)s%(hdr)s_init(%(obj_name)s,
            %(ver)s, %(length)s, %(cw)s)\
""" % dict(e_type=e_type, hdr=hdr, obj_name=obj_name, ver=ver,
           length=length, cw=cw)

def gen_list_first(out, cls, e_type):
    """
    Generate the body of a list_first operation
    @param cls The class name for which code is being generated
    @param e_type The element type of the list
    @param out The file to which to write
    """
    i_call = init_call(e_type, "obj", "list->version", "0", "1")
    if e_type in type_maps.inheritance_map:
        len_str = "obj->header.length"
    else:
        len_str = "obj->length"

    out.write("""
/**
 * Associate an iterator with a list
 * @param list The list to iterate over
 * @param obj The list entry iteration pointer
 * @return OF_ERROR_RANGE if the list is empty (end of list)
 *
 * The obj instance is completely initialized.  The caller is responsible
 * for cleaning up any wire buffers associated with obj before this call
 */

int
%(cls)s_first(%(cls)s_t *list,
    %(e_type)s_t *obj)
{
    int rv;

    %(i_call)s;
    if ((rv = of_list_first((of_object_t *)list, (of_object_t *)obj)) < 0) {
        return rv;
    }
""" % dict(cls=cls, e_type=e_type, i_call=i_call))

    # Special case flow_stats_entry lists

    out.write("""
    of_object_wire_init((of_object_t *) obj, %(u_type)s,
                        list->length);
    if (%(len_str)s == 0) {
        return OF_ERROR_PARSE;
    }

    return rv;
}
""" % dict(cls=cls, e_type=e_type, u_type=enum_name(e_type), len_str=len_str))


def gen_bind(out, cls, m_name, m_type):
    """
    Generate the body of a bind function
    @param out The file to which to write
    @param cls The class name for which code is being generated
    @param m_name The name of the data member
    @param m_type The type of the data member
    """

    bparams = ",\n    ".join(param_list(cls, m_name, "bind"))

    i_call = init_call(e_type, "child", "parent->version", "0", "1")

    out.write("""
/**
 * Bind the child object to the parent object for read processing
 * @param parent The parent object
 * @param child The child object
 *
 * The child obj instance is completely initialized.
 */

int
%(cls)s_%(m_name)_bind(%(cls)s_t *parent,
    %(e_type)s_t *child)
{
    int rv;

    %(i_call)s;

    /* Derive offset and length of child in parent */
    OF_TRY(of_object_child_attach(parent, child,
    if ((rv = of_list_first((of_object_t *)list, (of_object_t *)obj)) < 0) {
        return rv;
    }
""" % dict(cls=cls, e_type=e_type, i_call=i_call))

    # Special case flow_stats_entry lists

    out.write("""
    rv = of_object_wire_init((of_object_t *) obj, %(u_type)s,
                               list->length);
    if ((rv == OF_ERROR_NONE) && (%(len_str)s == 0)) {
        return OF_ERROR_PARSE;
    }

    return rv;
}
""" % dict(cls=cls, e_type=e_type, u_type=enum_name(e_type), len_str=len_str))


def gen_list_next(out, cls, e_type):
    """
    Generate the body of a list_next operation
    @param cls The class name for which code is being generated
    @param e_type The element type of the list
    @param out The file to which to write
    """

    if e_type in type_maps.inheritance_map:
        len_str = "obj->header.length"
    else:
        len_str = "obj->length"

    out.write("""
/**
 * Advance an iterator to the next element in a list
 * @param list The list being iterated
 * @param obj The list entry iteration pointer
 * @return OF_ERROR_RANGE if already at the last entry on the list
 *
 */

int
%(cls)s_next(%(cls)s_t *list,
    %(e_type)s_t *obj)
{
    int rv;

    if ((rv = of_list_next((of_object_t *)list, (of_object_t *)obj)) < 0) {
        return rv;
    }

    rv = of_object_wire_init((of_object_t *) obj, %(u_type)s,
        list->length);

    if ((rv == OF_ERROR_NONE) && (%(len_str)s == 0)) {
        return OF_ERROR_PARSE;
    }

    return rv;
}
""" % dict(cls=cls, e_type=e_type, u_type=enum_name(e_type), len_str=len_str))

def gen_list_append(out, cls, e_type):
    """
    Generate the body of a list append functions
    @param cls The class name for which code is being generated
    @param e_type The element type of the list
    @param out The file to which to write
    """

    out.write("""
/**
 * Set up to append an object of type %(e_type)s to an %(cls)s.
 * @param list The list that is prepared for append
 * @param obj Pointer to object to hold data to append
 *
 * The obj instance is completely initialized.  The caller is responsible
 * for cleaning up any wire buffers associated with obj before this call.
 *
 * See the generic documentation for of_list_append_bind.
 */

int
%(cls)s_append_bind(%(cls)s_t *list,
    %(e_type)s_t *obj)
{
    return of_list_append_bind((of_object_t *)list, (of_object_t *)obj);
}

/**
 * Append an item to a %(cls)s list.
 *
 * This copies data from item and leaves item untouched.
 *
 * See the generic documentation for of_list_append.
 */

int
%(cls)s_append(%(cls)s_t *list,
    %(e_type)s_t *item)
{
    return of_list_append((of_object_t *)list, (of_object_t *)item);
}

""" % dict(cls=cls, e_type=e_type))

def gen_list_accessors(out, cls):
    e_type = loxi_utils.list_to_entry_type(cls)
    gen_list_first(out, cls, e_type)
    gen_list_next(out, cls, e_type)
    gen_list_append(out, cls, e_type)

################################################################
#
# Accessor Functions
#
################################################################


def gen_accessor_declarations(out):
    """
    Generate the declaration of each version independent accessor

    @param out The file to which to write the decs
    """

    out.write("""
/****************************************************************
 *
 * Unified, per-member accessor function declarations
 *
 ****************************************************************/
""")
    for cls in of_g.standard_class_order:
        if cls in type_maps.inheritance_map:
            continue
        out.write("\n/* Unified accessor functions for %s */\n" % cls)
        for m_name in of_g.ordered_members[cls]:
            if m_name in of_g.skip_members:
                continue
            m_type = loxi_utils.member_base_type(cls, m_name)
            base_name = "%s_%s" % (cls, m_name)
            gparams = ",\n    ".join(param_list(cls, m_name, "get"))
            get_ret_type = accessor_return_type("get", m_type)
            sparams = ",\n    ".join(param_list(cls, m_name, "set"))
            set_ret_type = accessor_return_type("set", m_type)
            bparams = ",\n    ".join(param_list(cls, m_name, "bind"))
            bind_ret_type = accessor_return_type("bind", m_type)

            if loxi_utils.type_is_of_object(m_type):
                # Generate bind accessors, but not get accessor
                out.write("""
extern %(set_ret_type)s %(base_name)s_set(
    %(sparams)s);
extern %(bind_ret_type)s %(base_name)s_bind(
    %(bparams)s);
extern %(m_type)s *%(cls)s_%(m_name)s_get(
    %(cls)s_t *obj);
""" % dict(base_name=base_name, sparams=sparams, bparams=bparams,
           m_name=m_name, m_type=m_type, cls=cls,
           set_ret_type=set_ret_type, bind_ret_type=bind_ret_type))
            else:
                out.write("""
extern %(set_ret_type)s %(base_name)s_set(
    %(sparams)s);
extern %(get_ret_type)s %(base_name)s_get(
    %(gparams)s);
""" % dict(base_name=base_name, gparams=gparams, sparams=sparams,
           get_ret_type=get_ret_type, set_ret_type=set_ret_type))

        if loxi_utils.class_is_list(cls):
            e_type = loxi_utils.list_to_entry_type(cls)
            out.write("""
extern int %(cls)s_first(
    %(cls)s_t *list, %(e_type)s_t *obj);
extern int %(cls)s_next(
    %(cls)s_t *list, %(e_type)s_t *obj);
extern int %(cls)s_append_bind(
    %(cls)s_t *list, %(e_type)s_t *obj);
extern int %(cls)s_append(
    %(cls)s_t *list, %(e_type)s_t *obj);

/**
 * Iteration macro for list of type %(cls)s
 * @param list Pointer to the list being iterated over of
 * type %(cls)s
 * @param elt Pointer to an element of type %(e_type)s
 * @param rv On exiting the loop will have the value OF_ERROR_RANGE.
 */
#define %(u_cls)s_ITER(list, elt, rv)  \\
    for ((rv) = %(cls)s_first((list), (elt));   \\
         (rv) == OF_ERROR_NONE;   \\
         (rv) = %(cls)s_next((list), (elt)))
""" % dict(u_cls=cls.upper(), cls=cls, e_type=e_type))


def wire_accessor(m_type, a_type):
    """
    Returns the name of the a_type accessor for low level wire buff offset
    @param m_type The member type
    @param a_type The accessor type (set or get)
    """
    # Strip off _t if present
    if m_type in of_g.of_base_types:
        m_type = of_g.of_base_types[m_type]["short_name"]
    if m_type in of_g.of_mixed_types:
        m_type = of_g.of_mixed_types[m_type]["short_name"]
    if m_type[-2:] == "_t":
        m_type = m_type[:-2]
    if m_type == "octets":
        m_type = "octets_data"
    return "of_wire_buffer_%s_%s" % (m_type, a_type)

def get_len_macro(cls, m_type, version):
    """
    Get the length macro for m_type in cls
    """
    if m_type.find("of_match") == 0:
        return "_WIRE_MATCH_PADDED_LEN(obj, offset)"
    if m_type.find("of_list_oxm") == 0:
        return "wire_match_len(obj, 0) - 4"
    if loxi_utils.class_is_tlv16(m_type):
        return "_TLV16_LEN(obj, offset)"
    if cls == "of_packet_out" and m_type == "of_list_action_t":
        return "_PACKET_OUT_ACTION_LEN(obj)"
    # Default is everything to the end of the object
    return "_END_LEN(obj, offset)"

def gen_accessor_offsets(out, cls, m_name, version, a_type, m_type, offset):
    """
    Generate the sub-object offset and length calculations for accessors
    @param out File being written
    @param m_name Name of member
    @param version Wire version being processed
    @param a_type The accessor type (set or get)
    @param m_type The original member type
    @param offset The offset of the object or -1 if not fixed
    """
    # determine offset
    o_str = "%d" % offset  # Default is fixed length
    if offset == -1:
        # There are currently 4 special cases for this
        # In general, get offset and length of predecessor
        if (loxi_utils.cls_is_flow_mod(cls) and m_name == "instructions"):
            pass
        elif (cls == "of_flow_stats_entry" and m_name == "instructions"):
            pass
        elif (cls == "of_packet_in" and m_name == "data"):
            pass
        elif (cls == "of_packet_out" and m_name == "data"):
            pass
        else:
            debug("Error: Unknown member with offset == -1")
            debug("  cls %s, m_name %s, version %d" % (cls, m_name, version))
            sys.exit(1)
        o_str = "_%s_%s_OFFSET(obj)" % (cls.upper()[3:], m_name.upper())

    out.write("""\
        offset = %s;
""" % o_str);

    # This could be moved to main body but for version check
    if not loxi_utils.type_is_scalar(m_type):
        if loxi_utils.class_is_var_len(m_type[:-2], version) or \
                m_type == "of_match_t":
            len_macro = get_len_macro(cls, m_type, version)
        else:
            len_macro = "%d" % of_g.base_length[(m_type[:-2], version)]
        out.write("        cur_len = %s;\n" % len_macro)
    out.write("        break;\n")

def length_of(m_type, version):
    """
    Return the length of a type based on the version
    """
    if m_type in of_g.of_mixed_types:
        m_type = of_g.of_mixed_types[m_type][version]
    if m_type in of_g.of_base_types:
        return of_g.of_base_types[m_type]["bytes"]
    if (m_type[:-2], version) in of_g.base_length:
        return of_g.base_length[(m_type[:-2], version)]
    print "Unknown length request", m_type, version
    sys.exit(1)


def gen_get_accessor_body(out, cls, m_type, m_name):
    """
    Generate the common operations for a get accessor
    """
    if loxi_utils.type_is_scalar(m_type):
        ver = ""      # See if version required for scalar update
        if m_type in of_g.of_mixed_types:
            ver = "ver, "
        out.write("""\
    %(wa)s(%(ver)swbuf, abs_offset, %(m_name)s);
""" % dict(wa=wire_accessor(m_type, "get"), ver=ver, m_name=m_name))

        if m_type == "of_port_no_t":
           out.write("    OF_PORT_NO_VALUE_CHECK(*%s, ver);\n" % m_name)
    elif m_type == "of_octets_t":
        out.write("""\
    ASSERT(cur_len + abs_offset <= WBUF_CURRENT_BYTES(wbuf));
    %(m_name)s->bytes = cur_len;
    %(m_name)s->data = OF_WIRE_BUFFER_INDEX(wbuf, abs_offset);
""" % dict(m_name=m_name))
    elif m_type == "of_match_t":
        out.write("""
    ASSERT(cur_len + abs_offset <= WBUF_CURRENT_BYTES(wbuf));
    match_octets.bytes = cur_len;
    match_octets.data = OF_OBJECT_BUFFER_INDEX(obj, offset);
    OF_TRY(of_match_deserialize(ver, %(m_name)s, &match_octets));
""" % dict(m_name=m_name))
    else:
        out.write("""
    /* Initialize child */
    %(m_type)s_init(%(m_name)s, obj->version, 0, 1);
    /* Attach to parent */
    %(m_name)s->parent = (of_object_t *)obj;
    %(m_name)s->wire_object.wbuf = obj->wire_object.wbuf;
    %(m_name)s->wire_object.obj_offset = abs_offset;
    %(m_name)s->wire_object.owned = 0;
    %(m_name)s->length = cur_len;
""" % dict(m_type=m_type[:-2], m_name=m_name))


def gen_set_accessor_body(out, cls, m_type, m_name):
    """
    Generate the contents of a set accessor
    """
    if loxi_utils.type_is_scalar(m_type) or m_type == "of_octets_t":
        ver = "" # See if version required for scalar update
        if m_type in of_g.of_mixed_types:
            ver = "ver, "
        cur_len = "" # See if version required for scalar update
        if m_type == "of_octets_t":
            cur_len = ", cur_len"
            out.write("""\
    new_len = %(m_name)s->bytes;
    of_wire_buffer_grow(wbuf, abs_offset + (new_len - cur_len));
""" % dict(m_name=m_name))
        out.write("""\
    %(wa)s(%(ver)swbuf, abs_offset, %(m_name)s%(cur_len)s);
""" % dict(wa=wire_accessor(m_type, "set"), ver=ver, cur_len=cur_len,
           m_name=m_name))

    elif m_type == "of_match_t":
        out.write("""
    /* Match object */
    OF_TRY(of_match_serialize(ver, %(m_name)s, &match_octets));
    new_len = match_octets.bytes;
    of_wire_buffer_replace_data(wbuf, abs_offset, cur_len,
        match_octets.data, new_len);
    /* Free match serialized octets */
    FREE(match_octets.data);
""" % dict(m_name=m_name))

    else:  # Other object type
        out.write("\n    /* LOCI object type */")
        # Need to special case OXM list
        out.write("""
    new_len = %(m_name)s->length;
    /* If underlying buffer already shared; nothing to do */
    if (obj->wire_object.wbuf == %(m_name)s->wire_object.wbuf) {
        of_wire_buffer_grow(wbuf, abs_offset + new_len);
        /* Verify that the offsets are correct */
        ASSERT(abs_offset == OF_OBJECT_ABSOLUTE_OFFSET(%(m_name)s, 0));
        /* ASSERT(new_len == cur_len); */ /* fixme: may fail for OXM lists */
        return %(ret_success)s;
    }

    /* Otherwise, replace existing object in data buffer */
    of_wire_buffer_replace_data(wbuf, abs_offset, cur_len,
        OF_OBJECT_BUFFER_INDEX(%(m_name)s, 0), new_len);
""" % dict(m_name=m_name, ret_success=accessor_return_success("set", m_type)))

    if not loxi_utils.type_is_scalar(m_type):
        if cls == "of_packet_out" and m_type == "of_list_action_t":
            out.write("""
    /* Special case for setting action lengths */
    _PACKET_OUT_ACTION_LEN_SET(obj, %(m_name)s->length);
""" % dict(m_name=m_name))
        elif m_type not in ["of_match_t", "of_octets_t"]:
            out.write("""
    /* @fixme Shouldn't this precede copying value's data to buffer? */
    if (%(m_name)s->wire_length_set != NULL) {
        %(m_name)s->wire_length_set((of_object_t *)%(m_name)s, %(m_name)s->length);
    }
""" % dict(m_name=m_name))
        out.write("""
    /* Not scalar, update lengths if needed */
    delta = new_len - cur_len;
    if (delta != 0) {
        /* Update parent(s) */
        of_object_parent_length_update((of_object_t *)obj, delta);
    }
""")

def obj_assert_check(cls):
    """
    The body of the assert check for an accessor
    We allow all versions of add/delete/modify to use the same accessors
    """
    if cls in ["of_flow_modify", "of_flow_modify_strict",
               "of_flow_delete", "of_flow_delete_strict",
               "of_flow_add"]:
        return "IS_FLOW_MOD_SUBTYPE(obj->object_id)"
    else:
        return "obj->object_id == %s" % cls.upper()

def gen_of_object_get(out, cls, m_name, m_type):
    sub_cls = m_type[:-2]
    out.write("""
/**
 * Create a copy of %(m_name)s into a new variable of type %(m_type)s from
 * a %(cls)s instance.
 *
 * @param obj Pointer to the source of type %(cls)s_t
 * @returns A pointer to a new instance of type %(m_type)s whose contents
 * match that of %(m_name)s from source
 * @returns NULL if an error occurs
 */
%(m_type)s *
%(cls)s_%(m_name)s_get(%(cls)s_t *obj) {
    %(m_type)s _%(m_name)s;
    %(m_type)s *_%(m_name)s_ptr;

    %(cls)s_%(m_name)s_bind(obj, &_%(m_name)s);
    _%(m_name)s_ptr = (%(m_type)s *)of_object_dup(&_%(m_name)s);
    return _%(m_name)s_ptr;
}
""" % dict(m_name=m_name, m_type=m_type, cls=cls, sub_cls=sub_cls))

def gen_unified_acc_body(out, cls, m_name, ver_type_map, a_type, m_type):
    """
    Generate the body of a set or get accessor function

    @param out The file to which to write the decs
    @param cls The class name
    @param m_name The member name
    @param ver_type_map Maps (type, offset) pairs to a list of versions
    @param a_type The accessor type, set or get
    @param m_type The original member type

    The type values in ver_type_map are now ignored as we've pushed down
    the type munging to the lower level.

    This is unified because the version switch case processing is the
    same for both set and get
    """
    out.write("""{
    of_wire_buffer_t *wbuf;
    int offset = 0; /* Offset of value relative to the start obj */
    int abs_offset; /* Offset of value relative to start of wbuf */
    of_version_t ver;
""")

    if not loxi_utils.type_is_scalar(m_type):
        out.write("""\
    int cur_len = 0; /* Current length of object data */
""")
        if a_type == "set":
            out.write("""\
    int new_len, delta; /* For set, need new length and delta */
""")

    # For match, need octet string for set/get
    if m_type == "of_match_t":
        out.write("""\
    of_octets_t match_octets; /* Serialized string for match */
""")

    out.write("""
    ASSERT(%(assert_str)s);
    ver = obj->version;
    wbuf = OF_OBJECT_TO_WBUF(obj);
    ASSERT(wbuf != NULL);

    /* By version, determine offset and current length (where needed) */
    switch (ver) {
""" % dict(assert_str=obj_assert_check(cls)))

    for first in sorted(ver_type_map):
        (prev_t, prev_o) = ver_type_map[first]
        prev_len = length_of(prev_t, first)
        prev = first
        out.write("    case %s:\n" % of_g.wire_ver_map[first])
        break

    for next in sorted(ver_type_map):
        if next == first:
            continue

        (t, o) = ver_type_map[next]
        cur_len = length_of(t, next)
        if o == prev_o and cur_len == prev_len:
            out.write("    case %s:\n" % of_g.wire_ver_map[next])
            continue
        gen_accessor_offsets(out, cls, m_name, prev, a_type, m_type, prev_o)
        out.write("    case %s:\n" % of_g.wire_ver_map[next])
        (prev_t, prev_o, prev_len, prev) = (t, o, cur_len, next)

    gen_accessor_offsets(out, cls, m_name, next, a_type, m_type, prev_o)
    out.write("""\
    default:
        ASSERT(0);
    }

    abs_offset = OF_OBJECT_ABSOLUTE_OFFSET(obj, offset);
    ASSERT(abs_offset >= 0);
""")
    if not loxi_utils.type_is_scalar(m_type):
        out.write("    ASSERT(cur_len >= 0 && cur_len < 64 * 1024);\n")

    # Now generate the common accessor code
    if a_type in ["get", "bind"]:
        gen_get_accessor_body(out, cls, m_type, m_name)
    else:
        gen_set_accessor_body(out, cls, m_type, m_name)

    out.write("""
    OF_LENGTH_CHECK_ASSERT(obj);

    return %s;
}
""" % accessor_return_success(a_type, m_type))

def gen_of_obj_bind(out, cls, m_name, m_type, ver_type_map):
    """
    For generating the bind call for OF sub-objects
    """

    params = ",\n    ".join(param_list(cls, m_name, "bind"))
    out.write("""
/**
 * Bind an object of type %(m_type)s to the parent of type %(cls)s for
 * member %(m_name)s
 * @param obj Pointer to an object of type %(cls)s.
 * @param %(m_name)s Pointer to the child object of type
 * %(m_type)s to be filled out.
 * \ingroup %(cls)s
 *
 * The parameter %(m_name)s is filled out to point to the same underlying
 * wire buffer as its parent.
 *
 */
""" % dict(m_name=m_name, cls=cls, m_type=m_type))

    ret_type = accessor_return_type("bind", m_type)
    out.write("%s\n%s_%s_bind(\n    %s)\n" % (ret_type, cls, m_name, params))
    gen_unified_acc_body(out, cls, m_name, ver_type_map, "bind", m_type)

def gen_get_accessor(out, cls, m_name, m_type, ver_type_map):
    """
    For generating the get call for non- OF sub-objects
    """
    params = ",\n    ".join(param_list(cls, m_name, "get"))
    out.write("""
/**
 * Get %(m_name)s from an object of type %(cls)s.
 * @param obj Pointer to an object of type %(cls)s.
 * @param %(m_name)s Pointer to the child object of type
 * %(m_type)s to be filled out.
 *
 */
""" % dict(m_name=m_name, cls=cls, m_type=m_type))

    ret_type =  accessor_return_type("get", m_type)
    out.write("%s\n%s_%s_get(\n    %s)\n" % (ret_type, cls, m_name, params))
    gen_unified_acc_body(out, cls, m_name, ver_type_map, "get", m_type)

def gen_accessor_definitions(out, cls):
        for m_name in of_g.ordered_members[cls]:
            if m_name in of_g.skip_members:
                continue
            m_type = loxi_utils.member_base_type(cls, m_name)
            ver_type_map = field_ver_get(cls, m_name)

            # Generate get/bind pending on member type
            # FIXME:  Does this do the right thing for match?
            if loxi_utils.type_is_of_object(m_type):
                gen_of_obj_bind(out, cls, m_name, m_type, ver_type_map)
                gen_of_object_get(out, cls, m_name, m_type)
            else:
                gen_get_accessor(out, cls, m_name, m_type, ver_type_map)

            # Now generate set accessor for all objects
            params = ",\n    ".join(param_list(cls, m_name, "set"))
            out.write("""
/**
 * Set %(m_name)s in an object of type %(cls)s.
 * @param obj Pointer to an object of type %(cls)s.
""" % dict(m_name=m_name, cls=cls, m_type=m_type))
            if loxi_utils.type_is_scalar(m_type) or m_type == "of_octets_t":
                out.write("""\
 * @param %(m_name)s The value to write into the object
 */
""" % dict(m_name=m_name, cls=cls, m_type=m_type))
            else:
                out.write("""\
 * @param %(m_name)s Pointer to the child of type %(m_type)s.
 *
 * If the child's wire buffer is the same as the parent's, then
 * nothing is done as the changes have already been registered in the
 * parent.  Otherwise, the data in the child's wire buffer is inserted
 * into the parent's and the appropriate lengths are updated.
 */
""" % dict(m_name=m_name, cls=cls, m_type=m_type))
            ret_type = accessor_return_type("set", m_type)
            out.write("%s\n%s_%s_set(\n    %s)\n" % (ret_type, cls, m_name, params))
            gen_unified_acc_body(out, cls, m_name, ver_type_map, "set", m_type)

################################################################
#
# New/Delete Function Definitions
#
################################################################


################################################################
# First, some utility functions for new/delete
################################################################

def del_function_proto(cls):
    """
    Return the prototype for the delete operator for the given class
    @param cls The class name
    """
    fn = "void\n"
    return fn


################################################################
# Routines to generate the body of new/delete functions
################################################################

def gen_init_fn_body(cls, out):
    """
    Generate function body for init function
    @param cls The class name for the function
    @param out The file to which to write
    """
    if cls in type_maps.inheritance_map:
        param = "obj_p"
    else:
        param = "obj"

    out.write("""
/**
 * Initialize an object of type %(cls)s.
 *
 * @param obj Pointer to the object to initialize
 * @param version The wire version to use for the object
 * @param bytes How many bytes in the object
 * @param clean_wire Boolean: If true, clear the wire object control struct
 *
 * If bytes < 0, then the default fixed length is used for the object
 *
 * This is a "coerce" function that sets up the pointers for the
 * accessors properly.
 *
 * If anything other than 0 is passed in for the buffer size, the underlying
 * wire buffer will have 'grow' called.
 */

void
%(cls)s_init(%(cls)s_t *%(param)s,
    of_version_t version, int bytes, int clean_wire)
{
""" % dict(cls=cls, param=param))

    # Use an extra pointer to deal with inheritance classes
    if cls in type_maps.inheritance_map:
        out.write("""\
    %s_header_t *obj;

    obj = &obj_p->header;  /* Need instantiable subclass */
""" % cls)

    out.write("""
    ASSERT(of_object_fixed_len[version][%(enum)s] >= 0);
    if (clean_wire) {
        MEMSET(obj, 0, sizeof(*obj));
    }
    if (bytes < 0) {
        bytes = of_object_fixed_len[version][%(enum)s] + of_object_extra_len[version][%(enum)s];
    }
    obj->version = version;
    obj->length = bytes;
    obj->object_id = %(enum)s;
""" % dict(cls=cls, enum=enum_name(cls)))
    gen_coerce_ops(out, cls)

    out.write("""
    /* Grow the wire buffer */
    if (obj->wire_object.wbuf != NULL) {
        int tot_bytes;

        tot_bytes = bytes + obj->wire_object.obj_offset;
        of_wire_buffer_grow(obj->wire_object.wbuf, tot_bytes);
    }
}

""")

## @fixme This should also be updated once there is a map from
# class instance to wire length/type accessors
def gen_wire_push_fn(cls, out):
    """
    Generate the calls to push values into the wire buffer
    """
    if type_maps.class_is_virtual(cls):
        print "Push fn gen called for virtual class " + cls
        return

    out.write("""
/**
 * Helper function to push values into the wire buffer
 */
static inline int
%(cls)s_push_wire_values(%(cls)s_t *obj)
{
""" % dict(cls=cls))

    import loxi_globals
    uclass = loxi_globals.unified.class_by_name(cls)
    if uclass and not uclass.virtual and uclass.has_type_members:
        out.write("""
    %(cls)s_push_wire_types(obj);
""" % dict(cls=cls))

    if loxi_utils.class_is_message(cls):
        out.write("""
    /* Message obj; set length */
    of_message_t msg;

    if ((msg = OF_OBJECT_TO_MESSAGE(obj)) != NULL) {
        of_message_length_set(msg, obj->length);
    }
""" % dict(name = enum_name(cls)))

    else: # Not a message
        if loxi_utils.class_is_tlv16(cls):
            out.write("""
    /* TLV obj; set length */
    of_tlv16_wire_length_set((of_object_t *)obj, obj->length);
""" % dict(enum=enum_name(cls)))

        if loxi_utils.class_is_u16_len(cls) or cls == "of_packet_queue":
            out.write("""
    obj->wire_length_set((of_object_t *)obj, obj->length);
""")

        if cls == "of_meter_stats":
            out.write("""
    of_meter_stats_wire_length_set((of_object_t *)obj, obj->length);
""" % dict(enum=enum_name(cls)))

    out.write("""
    return OF_ERROR_NONE;
}
""")

def gen_new_fn_body(cls, out):
    """
    Generate function body for new function
    @param cls The class name for the function
    @param out The file to which to write
    """

    out.write("""
/**
 * \\defgroup %(cls)s %(cls)s
 */
""" % dict(cls=cls))

    if not type_maps.class_is_virtual(cls):
        gen_wire_push_fn(cls, out)

    out.write("""
/**
 * Create a new %(cls)s object
 *
 * @param version The wire version to use for the object
 * @return Pointer to the newly create object or NULL on error
 *
 * Initializes the new object with it's default fixed length associating
 * a new underlying wire buffer.
 *
 * Use new_from_message to bind an existing message to a message object,
 * or a _get function for non-message objects.
 *
 * \\ingroup %(cls)s
 */

%(cls)s_t *
%(cls)s_new(of_version_t version)
{
    %(cls)s_t *obj;
    int bytes;

    bytes = of_object_fixed_len[version][%(enum)s] + of_object_extra_len[version][%(enum)s];

    /* Allocate a maximum-length wire buffer assuming we'll be appending to it. */
    if ((obj = (%(cls)s_t *)of_object_new(OF_WIRE_BUFFER_MAX_LENGTH)) == NULL) {
        return NULL;
    }

    %(cls)s_init(obj, version, bytes, 0);
""" % dict(cls=cls, enum=enum_name(cls)))
    if not type_maps.class_is_virtual(cls):
        out.write("""
    if (%(cls)s_push_wire_values(obj) < 0) {
        FREE(obj);
        return NULL;
    }
""" % dict(cls=cls))

    match_offset = v3_match_offset_get(cls)
    if match_offset >= 0:
        # Init length field for match object
        out.write("""
    /* Initialize match TLV for 1.2 */
    /* FIXME: Check 1.3 below */
    if ((version == OF_VERSION_1_2) || (version == OF_VERSION_1_3)) {
        of_object_u16_set((of_object_t *)obj, %(match_offset)d + 2, 4);
    }
""" % dict(match_offset=match_offset))
    out.write("""
    return obj;
}
""" % dict(cls=cls))


def gen_from_message_fn_body(cls, out):
    """
    Generate function body for from_message function
    @param cls The class name for the function
    @param out The file to which to write
    """
    out.write("""
/**
 * Create a new %(cls)s object and bind it to an existing message
 *
 * @param msg The message to bind the new object to
 * @return Pointer to the newly create object or NULL on error
 *
 * \ingroup %(cls)s
 */

%(cls)s_t *
%(cls)s_new_from_message(of_message_t msg)
{
    %(cls)s_t *obj = NULL;
    of_version_t version;
    int length;

    if (msg == NULL) return NULL;

    version = of_message_version_get(msg);
    if (!OF_VERSION_OKAY(version)) return NULL;

    length = of_message_length_get(msg);

    if ((obj = (%(cls)s_t *)of_object_new(-1)) == NULL) {
        return NULL;
    }

    %(cls)s_init(obj, version, 0, 0);

    if ((of_object_buffer_bind((of_object_t *)obj, OF_MESSAGE_TO_BUFFER(msg),
                               length, OF_MESSAGE_FREE_FUNCTION)) < 0) {
       FREE(obj);
       return NULL;
    }
    obj->length = length;
    obj->version = version;

    return obj;
}
""" % dict(cls=cls))


################################################################
# Now the top level generator functions
################################################################

def gen_new_function_declarations(out):
    """
    Gerenate the header file declarations for new operators for all classes
    @param out The file to which to write the decs
    """

    out.write("""
/****************************************************************
 *
 * New operator declarations
 *
 * _new: Create a new object for writing; includes init
 * _new_from_message: Create a new instance of the object and bind the
 *    message data to the object
 * _init: Initialize and optionally allocate buffer space for an
 *    automatic instance
 *
 * _new and _from_message require a delete operation to be called
 * on the object.
 *
 ****************************************************************/
""")

    for cls in of_g.standard_class_order:
        out.write("""
extern %(cls)s_t *
    %(cls)s_new(of_version_t version);
""" % dict(cls=cls))
        if loxi_utils.class_is_message(cls):
            out.write("""extern %(cls)s_t *
    %(cls)s_new_from_message(of_message_t msg);
""" % dict(cls=cls))
        out.write("""extern void %(cls)s_init(
    %(cls)s_t *obj, of_version_t version, int bytes, int clean_wire);
""" % dict(cls=cls))

    out.write("""
/****************************************************************
 *
 * Delete operator static inline definitions.
 * These are here for type checking purposes only
 *
 ****************************************************************/
""")
    for cls in of_g.standard_class_order:
#        if cls in type_maps.inheritance_map:
#            continue
        out.write("""
/**
 * Delete an object of type %(cls)s_t
 * @param obj An instance of type %(cls)s_t
 *
 * \ingroup %(cls)s
 */
static inline void
%(cls)s_delete(%(cls)s_t *obj) {
    of_object_delete((of_object_t *)(obj));
}
""" % dict(cls=cls))

    out.write("""
typedef void (*of_object_init_f)(of_object_t *obj, of_version_t version,
    int bytes, int clean_wire);
extern const of_object_init_f of_object_init_map[];
""")

    out.write("""
/****************************************************************
 *
 * Function pointer initialization functions
 * These are part of the "coerce" type casting for objects
 *
 ****************************************************************/
""")

#
# @fixme Not clear that these should all be set for virtual fns
#
# @fixme Clean up.  should have a (language specific) map from class
# to length and type get/set functions
#

def gen_coerce_ops(out, cls):
    out.write("""
    /* Set up the object's function pointers */
""")

    uclass = loxi_globals.unified.class_by_name(cls)
    if uclass and not uclass.virtual and uclass.has_type_members:
        out.write("""
    obj->wire_type_set = %(cls)s_push_wire_types;
""" % dict(cls=cls))

    if loxi_utils.class_is_message(cls):
        out.write("""
    obj->wire_length_get = of_object_message_wire_length_get;
    obj->wire_length_set = of_object_message_wire_length_set;
""")
    else:
        if loxi_utils.class_is_tlv16(cls):
            if not (cls in type_maps.inheritance_map): # Don't set for super
                out.write("""
    obj->wire_length_set = of_tlv16_wire_length_set;
""")
            out.write("""
    obj->wire_length_get = of_tlv16_wire_length_get;
""")
            if loxi_utils.class_is_action(cls):
                out.write("""
    obj->wire_type_get = of_action_wire_object_id_get;
""")
            if loxi_utils.class_is_action_id(cls):
                out.write("""
    obj->wire_type_get = of_action_id_wire_object_id_get;
""")
            if loxi_utils.class_is_instruction(cls):
                out.write("""
    obj->wire_type_get = of_instruction_wire_object_id_get;
""")
            if loxi_utils.class_is_queue_prop(cls):
                    out.write("""
    obj->wire_type_get = of_queue_prop_wire_object_id_get;
""")
            if loxi_utils.class_is_table_feature_prop(cls):
                    out.write("""
    obj->wire_type_get = of_table_feature_prop_wire_object_id_get;
""")
            if loxi_utils.class_is_meter_band(cls):
                    out.write("""
    obj->wire_type_get = of_meter_band_wire_object_id_get;
""")
            if loxi_utils.class_is_hello_elem(cls):
                    out.write("""
    obj->wire_type_get = of_hello_elem_wire_object_id_get;
""")
        if loxi_utils.class_is_oxm(cls):
            out.write("""
    obj->wire_length_get = of_oxm_wire_length_get;
    obj->wire_type_get = of_oxm_wire_object_id_get;
""")
        if loxi_utils.class_is_u16_len(cls):
            out.write("""
    obj->wire_length_get = of_u16_len_wire_length_get;
    obj->wire_length_set = of_u16_len_wire_length_set;
""")
        if cls == "of_packet_queue":
            out.write("""
    obj->wire_length_get = of_packet_queue_wire_length_get;
    obj->wire_length_set = of_packet_queue_wire_length_set;
""")
#        if cls == "of_list_meter_band_stats":
#            out.write("""
#    obj->wire_length_get = of_list_meter_band_stats_wire_length_get;
#""")
        if cls == "of_meter_stats":
            out.write("""
    obj->wire_length_get = of_meter_stats_wire_length_get;
    obj->wire_length_set = of_meter_stats_wire_length_set;
""")

def gen_new_function_definitions(out, cls):
    """
    Generate the new operator for all classes

    @param out The file to which to write the functions
    """

    gen_new_fn_body(cls, out)
    gen_init_fn_body(cls, out)
    if loxi_utils.class_is_message(cls):
        gen_from_message_fn_body(cls, out)

"""
Document generation functions

The main reason this is here is to generate documentation per
accessor that indicates the versions that support the interface.
"""


def gen_accessor_doc(out, name):
    """
    Generate documentation for each accessor function that indicates
    the versions supporting the accessor.
    """

    common_top_matter(out, name)

    out.write("/* DOCUMENTATION ONLY */\n")

    for cls in of_g.standard_class_order:
        if cls in type_maps.inheritance_map:
            pass # Check this

        out.write("""
/**
 * Structure for %(cls)s object.  Get/set
 * accessors available in all versions unless noted otherwise
 *
""" % dict(cls=cls))
        if loxi_utils.class_is_list(cls):
            out.write("""\
 * @param first Function of type %(cls)s_first_f.
 * Setup a TBD class object to the first entry in the list
 * @param next Function of type %(cls)s_next_f.
 * Advance a TBD class object to the next entry in the list
 * @param append_bind Function of type %(cls)s_append_bind_f
 * Setup a TBD class object for append to the end of the current list
 * @param append  Function of type @ref %(cls)s_append_f.
 * Copy an item to the end of a list
""" % dict(cls=cls))

        for m_name in of_g.ordered_members[cls]:
            if m_name in of_g.skip_members:
                continue
            ver_type_map = field_ver_get(cls, m_name)
            (m_type, get_rv) = get_acc_rv(cls, m_name)
            if len(ver_type_map) == 3:
                # ver_string = "Available in all versions"
                ver_string = ""
            else:
                ver_string = "("
                for ver in sorted(ver_type_map):
                    ver_string += " " + of_g.short_version_names[ver]
                ver_string += ")."

            f_name = acc_name(cls, m_name)
            out.write("""\
 * @param %(m_name)s_get/set %(ver_string)s
 *   Accessors for %(m_name)s, a variable of type %(m_type)s.  Functions
 *   are of type %(f_name)s_get_f and _set_f.
 *
""" % dict(f_name=f_name, m_name=m_name, ver_string=ver_string, m_type=m_type))

        out.write("""\
 */
typedef struct %(cls)s_s %(cls)s_t;
""" % dict(cls=cls))

    out.write("#endif /* _LOCI_DOC_H_ */\n")

################################################################
#
# For fun, here are some unified, traditional C structure representation
#
################################################################

def gen_cof_to_wire(out):
    pass

def gen_wire_to_cof(out):
    pass

def gen_cof_instance(out, cls):
    out.write("struct c%s_s {\n" % cls)
    for m in of_g.ordered_members[cls]:
        if m in of_g.skip_members:
            continue
        entry = of_g.unified[cls]["union"][m]
        cof_type = type_to_cof_type(entry["m_type"])
        out.write("    %-20s %s;\n" % (cof_type, m))
    out.write("};\n\n");

def gen_cof_structs(out):
    """
    Generate non-version specific (common) representation of structures

    @param out The file to which to write the functions
    """

    out.write("\n/* Common, unified OpenFlow structure representations */\n")
    for cls in of_g.standard_class_order:
        if cls in type_maps.inheritance_map:
            continue
        gen_cof_instance(out, cls)

################################################################
#
# Generate code samples for applications.
#
################################################################

def gen_code_samples(out, name):
    out.write("""
#if 0 /* Do not compile in */
/**
 * @file %(name)s
 *
 * These are code samples for inclusion in other components
 */

""" % dict(name=name))

    gen_jump_table_template(out)
    # These are messages that a switch might expect.
    msg_list = ["of_echo_request",
                "of_hello",
                "of_packet_in",
                "of_packet_out",
                "of_port_mod",
                "of_port_stats_request",
                "of_queue_get_config_request",
                "of_queue_stats_request",
                "of_flow_add",
                "of_flow_modify",
                "of_flow_modify_strict",
                "of_flow_delete",
                "of_flow_delete_strict",
                "of_get_config_request",
                "of_flow_stats_request",
                "of_barrier_request",
                "of_echo_reply",
                "of_aggregate_stats_request",
                "of_desc_stats_request",
                "of_table_stats_request",
                "of_features_request",
                "of_table_mod",
                "of_set_config",
                "of_experimenter",
                "of_experimenter_stats_request",
                "of_group_desc_stats_request",
                "of_group_features_stats_request",
                "of_role_request"]

    gen_message_handler_templates(out, msgs=msg_list)

    out.write("""
#endif
""")

def gen_jump_table_template(out=sys.stdout, all_unhandled=True,
                            cxn_type="ls_cxn_handle_t",
                            unhandled="unhandled_message"):
    """
    Generate a template for a jump table.
    @param out The file to which to write the functions
    """
    out.write("""
/*
 * Simple jump table definition for message handling
 */
typedef int (*msg_handler_f)(%(cxn_type)s cxn, of_object_t *obj);
typedef msg_handler_f msg_jump_table_t[OF_MESSAGE_OBJECT_COUNT];

/* Jump table template for message objects */
extern msg_jump_table_t jump_table;

/* C-code template */
msg_jump_table_t jump_table = {
    %(unhandled)s, /* OF_OBJECT; place holder for generic object  */
""" % dict(unhandled=unhandled, cxn_type=cxn_type))
    count = 0
    fn_name = unhandled
    for cls in of_g.ordered_messages:
        comma = ","
        count += 1
        if count == len(of_g.ordered_messages):
            comma = " "
        if not all_unhandled:
            fn_name = "%s_handler" % cls[3:]
        out.write("    %s%s /* %s */\n" % (fn_name, comma, enum_name(cls)))

    out.write("};\n")

def gen_message_switch_stmt_tmeplate(out=sys.stdout, all_unhandled=True,
                                     cxn_type="ls_cxn_handle_t",
                                     unhandled="unhandled_message"):
    out.write("""
/*
 * Simple switch statement for message handling
 */

    switch (obj->object_id):
""")
    fn_name = unhandled
    for cls in of_g.ordered_messages:
        if not all_unhandled:
            fn_name = "%s_handler" % cls[3:]
        out.write("""
    case %(enum)s:
        rv = %(fn_name)s(cxn, obj);
        break;
""" % dict(fn_name=fn_name, cls=cls, enum=enum_name(cls)))
    out.write("""
    default:
        rv = LS_ERROR_PARAM;
        break;
    }

    TRACE("Handled msg %p with rv %d (%s)", obj, rv, ls_error_strings[rv]);

    return rv;
""")


def gen_message_handler_templates(out=sys.stdout, cxn_type="ls_cxn_handle_t",
                                  unhandled="unhandled_message", msgs=None):
    gen_jump_table_template(out, False, cxn_type)
    out.write("""
/**
 * Function for unhandled message
 */
static int
unhandled_message(%(cxn_type)s cxn, of_object_t *obj)
{
    (void)cxn;
    (void)obj;
    TRACE("Unhandled message %%p.  Object id %%d", obj, obj->object_id);

    return LS_ERROR_UNAVAIL;
}
""" % dict(unhandled=unhandled, cxn_type=cxn_type))

    if not msgs:
        msgs = of_g.ordered_messages
    for cls in msgs:
        out.write("""
/**
 * Handle a %(s_cls)s message
 * @param cxn Connection handler for the owning connection
 * @param _obj Generic type object for the message to be coerced
 * @returns Error code
 */

static int
%(s_cls)s_handler(%(cxn_type)s cxn, of_object_t *_obj)
{
    %(cls)s_t *obj;

    TRACE("Handling %(cls)s message: %%p.", obj);
    obj = (%(cls)s_t *)_obj;

    /* Handle object of type %(cls)s_t */

    return LS_ERROR_NONE;
}
""" % dict(s_cls=cls[3:], cls=cls, cxn_type=cxn_type))
    gen_message_switch_stmt_tmeplate(out, False, cxn_type)
