# 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 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_match_struct(out)
    c_match.gen_match_comp(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)->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))

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)

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

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];
""")
    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) \\
    LOCI_ASSERT(((obj)->parent != NULL) || \\
     ((obj)->wbuf == NULL) || \\
     (WBUF_CURRENT_BYTES((obj)->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("""
static inline const char *
of_class_name(of_object_t *obj)
{
    return of_object_id_str[obj->object_id];
}
""")

    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_4)

""")
    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[];

#ifdef __GNUC__
#define LOCI_NORETURN_ATTR __attribute__((__noreturn__))
#else
#define LOCI_NORETURN_ATTR
#endif

extern void loci_assert_fail(
    const char *cond,
    const char *file,
    unsigned int line) LOCI_NORETURN_ATTR;

#ifndef NDEBUG
#define LOCI_ASSERT(val) ((val) ? (void)0 : loci_assert_fail(#val, __FILE__, __LINE__))
#else
#define LOCI_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;

typedef struct of_bitmap_512_s {
    uint64_t words[8];
} of_bitmap_512_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;

extern const of_bitmap_512_t of_bitmap_512_all_ones;
extern const of_bitmap_512_t of_bitmap_512_all_zeroes;

/**
 * Generic zero and all-ones values of size 16 bytes.
 *
 * bitmap_512 is longest data type we worry about for comparisons
 */
#define of_all_zero_value of_bitmap_512_all_zeroes
#define of_all_ones_value of_bitmap_512_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_app_code_t[OF_APP_CODE_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 char of_str64_t[64];
typedef char of_str32_t[32];
typedef char of_str6_t[6];

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

typedef struct of_checksum_128_s {
    uint64_t hi;
    uint64_t lo;
} of_checksum_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__ == __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) & 0xff) << 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
""")

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>
#include <loci/loci_class_metadata.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
 * 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("""
    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))

################################################################
#
# 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 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_struct_typedefs(out):
    """
    Generate typedefs for all struct objects
    @param out The file for output, already open
    """

    out.write("\n/* LOCI object typedefs */\n")
    for cls in of_g.standard_class_order:
        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);

""")

################################################################
#
# 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 type_maps.class_is_virtual(cls) and not loxi_utils.class_is_list(cls):
            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, of_object_t *iter);
extern int %(cls)s_next(
    %(cls)s_t *list, of_object_t *iter);
extern int %(cls)s_append_bind(
    %(cls)s_t *list, of_object_t *iter);
extern int %(cls)s_append(
    %(cls)s_t *list, of_object_t *iter);

/**
 * 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_name, 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)"
    if cls == "of_bsn_gentable_entry_add" and m_name == "key":
        return "of_object_u16_get(obj, 18)"
    if cls == "of_bsn_gentable_entry_desc_stats_entry" and m_name == "key":
        return "of_object_u16_get(obj, 2)"
    if cls == "of_bsn_gentable_entry_stats_entry" and m_name == "key":
        return "of_object_u16_get(obj, 2)"
    # 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
        elif (cls == "of_bsn_gentable_entry_add" and m_name == "value"):
            pass
        elif (cls == "of_bsn_gentable_entry_desc_stats_entry" and m_name == "value"):
            pass
        elif (cls == "of_bsn_gentable_entry_stats_entry" and m_name == "stats"):
            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_name, 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("""\
    LOCI_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("""
    LOCI_ASSERT(cur_len + abs_offset <= WBUF_CURRENT_BYTES(wbuf));
    OF_TRY(of_match_deserialize(ver, %(m_name)s, obj, offset, cur_len));
""" % dict(m_name=m_name))
    elif m_type == "of_oxm_t":
        out.write("""
    /* Initialize child */
    %(m_type)s_init(%(m_name)s, obj->version, 0, 1);
    /* Attach to parent */
    of_object_attach(obj, %(m_name)s, offset, cur_len);
    of_object_wire_init(%(m_name)s, OF_OXM, 0);
""" % dict(m_type=m_type[:-2], m_name=m_name))
    elif m_type == "of_bsn_vport_t":
        out.write("""
    /* Initialize child */
    %(m_type)s_init(%(m_name)s, obj->version, 0, 1);
    /* Attach to parent */
    of_object_attach(obj, %(m_name)s, offset, cur_len);
    of_object_wire_init(%(m_name)s, OF_BSN_VPORT, 0);
""" % dict(m_type=m_type[:-2], m_name=m_name))
    else:
        out.write("""
    /* Initialize child */
    %(m_type)s_init(%(m_name)s, obj->version, 0, 1);
    /* Attach to parent */
    of_object_attach(obj, %(m_name)s, offset, 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_octets_t match_octets;
        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->wbuf == %(m_name)s->wbuf) {
        of_wire_buffer_grow(wbuf, abs_offset + new_len);
        /* Verify that the offsets are correct */
        LOCI_ASSERT(abs_offset == OF_OBJECT_ABSOLUTE_OFFSET(%(m_name)s, 0));
        /* LOCI_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 cls == "of_bsn_gentable_entry_add" and m_name == "key":
            out.write("""
    /* Special case for setting key length */
    of_object_u16_set(obj, 18, %(m_name)s->length);
""" % dict(m_name=m_name))
        elif cls in ["of_bsn_gentable_entry_desc_stats_entry", "of_bsn_gentable_entry_stats_entry"] and m_name == "key":
            out.write("""
    /* Special case for setting key length */
    of_object_u16_set(obj, 2, %(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? */
    of_object_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 */
""")

    out.write("""
    LOCI_ASSERT(%(assert_str)s);
    ver = obj->version;
    wbuf = OF_OBJECT_TO_WBUF(obj);
    LOCI_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:
        LOCI_ASSERT(0);
    }

    abs_offset = OF_OBJECT_ABSOLUTE_OFFSET(obj, offset);
    LOCI_ASSERT(abs_offset >= 0);
""")
    if not loxi_utils.type_is_scalar(m_type):
        out.write("    LOCI_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
#
################################################################

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

    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(of_object_t *obj,
    of_version_t version, int bytes, int clean_wire)
{
    LOCI_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];
    }
    obj->version = version;
    obj->length = bytes;
    obj->object_id = %(enum)s;

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

        tot_bytes = bytes + obj->obj_offset;
        of_wire_buffer_grow(obj->wbuf, tot_bytes);
    }
}
""" % dict(cls=cls, enum=enum_name(cls)))

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))

    uclass = loxi_globals.unified.class_by_name(cls)
    is_fixed_length = uclass and uclass.is_fixed_length
    max_length = is_fixed_length and "bytes" or "OF_WIRE_BUFFER_MAX_LENGTH"

    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.
 *
 * \\ingroup %(cls)s
 */

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

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

    if ((obj = of_object_new(%(max_length)s)) == NULL) {
        return NULL;
    }

    %(cls)s_init(obj, version, bytes, 0);
""" % dict(cls=cls, enum=enum_name(cls), max_length=max_length))
    if not type_maps.class_is_virtual(cls):
        from codegen import class_metadata_dict
        metadata = class_metadata_dict[cls]

        if metadata.wire_type_set != 'NULL':
            out.write("""\
    %s(obj);
""" % metadata.wire_type_set)

        if metadata.wire_length_set != 'NULL':
            out.write("""\
    %s(obj, obj->length);
""" % metadata.wire_length_set)

    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 */
    if ((version >= OF_VERSION_1_2)) {
        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))


################################################################
# 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
 * _init: Initialize and optionally allocate buffer space for an
 *    automatic instance
 *
 * _new and requires a delete operation to be called on the object.
 *
 ****************************************************************/
""")

    for cls in of_g.standard_class_order:
        out.write("""
extern of_object_t *
    %(cls)s_new(of_version_t version);
""" % dict(cls=cls))
        out.write("""extern void %(cls)s_init(
    of_object_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:
        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(of_object_t *obj) {
    of_object_delete(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
 *
 ****************************************************************/
""")

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)

"""
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 type_maps.class_is_virtual(cls):
            pass

        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")
