# 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];
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) \\
    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_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[];

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

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 char of_str64_t[64];

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

/****************************************************************
 *
 * 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>
#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
 * 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("""
    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 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_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);

""")

################################################################
#
# 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_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_header_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_header_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
    """
    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("""
    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] + 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)))

    out.write("""
    /* 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);
    }
}

""")

## @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("""
    of_object_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)

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

%(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];

    if ((obj = (%(cls)s_t *)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):
        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))


################################################################
# 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 %(cls)s_t *
    %(cls)s_new(of_version_t version);
""" % 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
 *
 ****************************************************************/
""")

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