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

"""
@brief Test case generation functions

@fixme Update the following
The following components are generated.

test_common.[ch]:  A collection of common code for tests.  Currently
this includes the ability to set the scalar members of an object with
incrementing values and then similarly verify those values

test_scalar_acc.c: Instantiate each type of object, then set and get
scalar values in the objects.

test_list.c: Instantiate each type of list, add an element of each
type the list supports, setting scalar values of the elements.

test_match.c: Various tests for match objects

test_msg.c: Instantiate top level messages

These will move towards unified tests that do the following:

Create or init an object.
Populate the object with incrementing values.
Possibly transform the object in some way (e.g., run the underlying
wire buffer through a parse routine).
Verify that the members all have the appropriate value

Through out, checking the consistency of memory and memory operations
is done with mcheck (if available).

"""

import sys
import c_gen.of_g_legacy as of_g
import c_gen.match as match
import c_gen.flags as flags
from generic_utils import *
import c_gen.type_maps as type_maps
import c_gen.loxi_utils_legacy as loxi_utils
import c_gen.identifiers as identifiers
import util
import test_data
import loxi_globals
from loxi_ir import *

def var_name_map(m_type):
    """
    Map a type to a generic variable name for the type.
    @param m_type The data type

    Used mostly in test code generation, but also for the dup functions.
    """
    _var_name_map= dict(
        uint8_t="val8",
        uint16_t="val16",
        uint32_t="val32",
        uint64_t="val64",
        of_ipv4_t="ipv4",
        of_port_no_t="port_no",
        of_fm_cmd_t="fm_cmd",
        of_wc_bmap_t="wc_bmap",
        of_match_bmap_t = "match_bmap",
        of_port_name_t="port_name",
        of_table_name_t="table_name",
        of_desc_str_t="desc_str",
        of_serial_num_t="ser_num",
        of_str64_t="str64",
        of_mac_addr_t="mac_addr",
        of_ipv6_t="ipv6",
        # Non-scalars; more TBD
        of_octets_t="octets",
        of_meter_features_t="features",
        of_match_t="match",
        of_oxm_header_t="oxm",
        of_bsn_vport_header_t="bsn_vport",
        # BSN extensions
        of_bsn_vport_q_in_q_t="vport",
        of_bitmap_128_t="bitmap_128",
        of_checksum_128_t="checksum_128",
        )

    if m_type.find("of_list_") == 0:
        return "list"
    if m_type in of_g.of_mixed_types:
        return of_g.of_mixed_types[m_type]["short_name"]
    return _var_name_map[m_type]

integer_types = ["uint8_t", "uint16_t", "uint32_t", "uint64_t",
                 "of_port_no_t", "of_fm_cmd_t", "of_wc_bmap_t",
                 "of_match_bmap_t", "of_ipv4_t"]
string_types = [ "of_port_name_t", "of_table_name_t",
                "of_desc_str_t", "of_serial_num_t", "of_mac_addr_t",
                "of_ipv6_t", "of_bitmap_128_t", "of_checksum_128_t",
                "of_str64_t"]

scalar_types = integer_types[:]
scalar_types.extend(string_types)

# When embedding an object inside of another object we have to pick a single
# subclass to use, unlike lists where we use all subclasses.
embedded_subclasses = {
    'of_oxm_header_t': 'of_oxm_eth_type',
    'of_bsn_vport_header_t': 'of_bsn_vport_q_in_q',
}

def ignore_member(cls, version, m_name, m_type):
    """
    Filter out names or types that either don't have accessors
    or those that should not be messed with
    or whose types we're not ready to deal with yet.
    """

    uclass = loxi_globals.unified.class_by_name(cls)
    if not uclass:
        return True

    if not isinstance(uclass.member_by_name(m_name), OFDataMember):
        return True

    return loxi_utils.skip_member_name(m_name) or m_type not in scalar_types

def gen_fill_string(out):
    out.write("""

/**
 * The increment to use on values inside a string
 */
#define OF_TEST_STR_INCR 3

/**
 * Fill in a buffer with incrementing values starting
 * at the given offset with the given value
 * @param buf The buffer to fill
 * @param value The value to use for data
 * @param len The number of bytes to fill
 */

void
of_test_str_fill(uint8_t *buf, int value, int len)
{
    int i;

    for (i = 0; i < len; i++) {
        *buf = value;
        value += OF_TEST_STR_INCR;
        buf++;
    }
}

/**
 * Given a buffer, verify that it's filled as above
 * @param buf The buffer to check
 * @param value The value to use for data
 * @param len The number of bytes to fill
 * @return Boolean True on equality (success)
 */

int
of_test_str_check(uint8_t *buf, int value, int len)
{
    int i;
    uint8_t val8;

    val8 = value;

    for (i = 0; i < len; i++) {
        if (*buf != val8) {
            return 0;
        }
        val8 += OF_TEST_STR_INCR;
        buf++;
    }

    return 1;
}

/**
 * Global that determines how octets should be populated
 * -1 means use value % MAX (below) to determine length
 * 0, 1, ... means used that fixed length
 *
 * Note: Was 16K, but that made objects too big.  May add flexibility
 * to call populate with a max parameter for length
 */
int octets_pop_style = -1;
#define OCTETS_MAX_VALUE (128) /* 16K was too big */
#define OCTETS_MULTIPLIER 6367 /* A prime */

int
of_octets_populate(of_octets_t *octets, int value)
{
    if (octets_pop_style < 0) {
        octets->bytes = (value * OCTETS_MULTIPLIER) % OCTETS_MAX_VALUE;
    } else {
        octets->bytes = octets_pop_style;
    }

    if (octets->bytes != 0) {
        if ((octets->data = (uint8_t *)MALLOC(octets->bytes)) == NULL) {
            return 0;
        }
        of_test_str_fill(octets->data, value, octets->bytes);
        value += 1;
    }

    return value;
}

int
of_octets_check(of_octets_t *octets, int value)
{
    int len;

    if (octets_pop_style < 0) {
        len =  (value * OCTETS_MULTIPLIER) % OCTETS_MAX_VALUE;
        TEST_ASSERT(octets->bytes == len);
    } else {
        TEST_ASSERT(octets->bytes == octets_pop_style);
    }

    if (octets->bytes != 0) {
        TEST_ASSERT(of_test_str_check(octets->data, value, octets->bytes)
            == 1);
        value += 1;
    }

    return value;
}

int
of_match_populate(of_match_t *match, of_version_t version, int value)
{
    MEMSET(match, 0, sizeof(*match));
    match->version = version;
""")

    def populate_match_version(wire_version, keys):
        out.write("""
    if (version == %d) {\
""" % wire_version)
        for key in keys:
            entry = match.of_match_members[key]
            out.write("""
        OF_MATCH_MASK_%(ku)s_EXACT_SET(match);
        VAR_%(u_type)s_INIT(match->fields.%(key)s, value);
        value += 1;
""" % dict(key=key, u_type=entry["m_type"].upper(), ku=key.upper()))
        out.write("""
    }

""")

    for wire_version, match_keys in match.match_keys.items():
        populate_match_version(wire_version, match_keys)

    out.write("""
    if (value % 2) {
        /* Sometimes set ipv4 addr masks to non-exact */
        match->masks.ipv4_src = 0xffff0000;
        match->masks.ipv4_dst = 0xfffff800;
    }

    /* Restrict values according to masks */
    of_memmask(&match->fields, &match->masks, sizeof(match->fields));
    return value;
}

int
of_match_check(of_match_t *match, of_version_t version, int value)
{
    of_match_t check;

    value = of_match_populate(&check, match->version, value);
    TEST_ASSERT(value != 0);
    TEST_ASSERT(MEMCMP(match, &check, sizeof(check)) == 0);

    return value;
}
""")

def gen_common_test_header(out, name):
    loxi_utils.gen_c_copy_license(out)
    out.write("""
/*
 * Test header file
 *
 * AUTOMATICALLY GENERATED FILE.  Edits will be lost on regen.
 */

#if !defined(_TEST_COMMON_H_)
#define _TEST_COMMON_H_

#define DISABLE_WARN_UNUSED_RESULT
#include <loci/loci.h>
#include <locitest/of_dup.h>
#include <locitest/unittest.h>

extern int global_error;
extern int exit_on_error;

/* @todo Make option for -k to continue tests if errors */
#define RUN_TEST(test) do {                                             \\
        int rv;                                                         \\
        TESTCASE(test, rv);                                             \\
        if (rv != TEST_PASS) {                                          \\
            global_error=1;                                             \\
            if (exit_on_error) return(1);                               \\
        }                                                               \\
    } while(0)

#define TEST_OK(op) TEST_ASSERT((op) == OF_ERROR_NONE)
#define TEST_INDIGO_OK(op) TEST_ASSERT((op) == INDIGO_ERROR_NONE)

/*
 * Declarations of functions to populate scalar values in a a class
 */

extern void of_test_str_fill(uint8_t *buf, int value, int len);
extern int of_test_str_check(uint8_t *buf, int value, int len);


extern int of_octets_populate(of_octets_t *octets, int value);
extern int of_octets_check(of_octets_t *octets, int value);
extern int of_match_populate(of_match_t *match, of_version_t version,
                             int value);
extern int of_match_check(of_match_t *match, of_version_t version, int value);
extern int test_ident_macros(void);
extern int test_dump_objs(void);

/* In test_match_utils.c */
extern int test_match_utils(void);

extern int run_unified_accessor_tests(void);
extern int run_match_tests(void);
extern int run_utility_tests(void);

extern int run_scalar_acc_tests(void);
extern int run_list_tests(void);
extern int run_message_tests(void);

extern int run_validator_tests(void);

extern int run_list_limits_tests(void);

extern int test_ext_objs(void);
extern int test_datafiles(void);

""")

    for version in of_g.of_version_range:
        for cls in of_g.standard_class_order:
            if not loxi_utils.class_in_version(cls, version):
                continue
            if type_maps.class_is_inheritance_root(cls):
                continue
            out.write("""
extern int %(cls)s_%(v_name)s_populate(
    %(cls)s_t *obj, int value);
extern int %(cls)s_%(v_name)s_check(
    %(cls)s_t *obj, int value);
extern int %(cls)s_%(v_name)s_populate_scalars(
    %(cls)s_t *obj, int value);
extern int %(cls)s_%(v_name)s_check_scalars(
    %(cls)s_t *obj, int value);
""" % dict(cls=cls, v_name=loxi_utils.version_to_name(version)))

    out.write("""
/*
 * Declarations for list population and check primitives
 */
""")

    for version in of_g.of_version_range:
        for cls in of_g.ordered_list_objects:
            if version in of_g.unified[cls]:
               out.write("""
extern int
    list_setup_%(cls)s_%(v_name)s(
    %(cls)s_t *list, int value);
extern int
    list_check_%(cls)s_%(v_name)s(
    %(cls)s_t *list, int value);
""" % dict(cls=cls, v_name=loxi_utils.version_to_name(version)))

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

def gen_common_test(out, name):
    """
    Generate common test content including main
    """
    loxi_utils.gen_c_copy_license(out)
    out.write("""
/*
 * Common test code for LOCI
 *
 * AUTOMATICALLY GENERATED FILE.  Edits will be lost on regen.
 */

#define DISABLE_WARN_UNUSED_RESULT
#include "loci_log.h"
#include <loci/loci_obj_dump.h>
#include <locitest/unittest.h>
#include <locitest/test_common.h>

/* mcheck is a glibc extension */
#if defined(__linux__)
#include <mcheck.h>
#define MCHECK_INIT mcheck(NULL)
#else
#define MCHECK_INIT do { } while (0)
#endif

/**
 * Exit on error if set to 1
 */
int exit_on_error = 1;

/**
 * Global error state: 0 is okay, 1 is error
 */
int global_error = 0;

extern int run_unified_accessor_tests(void);
extern int run_match_tests(void);
extern int run_utility_tests(void);

extern int run_scalar_acc_tests(void);
extern int run_list_tests(void);
extern int run_message_tests(void);

/**
 * Macros for initializing and checking scalar types
 *
 * @param var The variable being initialized or checked
 * @param val The integer value to set/check against, see below
 *
 * Note that equality means something special for strings.  Each byte
 * is initialized to an incrementing value.  So check is done against that.
 *
 */

""")
    for t in scalar_types:
        if t in integer_types:
            out.write("""
#define VAR_%s_INIT(var, val) var = (%s)(val)
#define VAR_%s_CHECK(var, val) ((var) == (%s)(val))
""" % (t.upper(), t, t.upper(), t))
        else:
            out.write("""
#define VAR_%s_INIT(var, val) \\
    of_test_str_fill((uint8_t *)&(var), val, sizeof(var))
#define VAR_%s_CHECK(var, val) \\
    of_test_str_check((uint8_t *)&(var), val, sizeof(var))
""" % (t.upper(), t.upper()))

    gen_fill_string(out)
    gen_scalar_set_check_funs(out)
    gen_list_set_check_funs(out)
    gen_unified_accessor_funs(out)

    gen_ident_tests(out)
    gen_log_test(out)

def gen_message_scalar_test(out, name):
    """
    Generate test cases for message objects, scalar accessors
    """

    loxi_utils.gen_c_copy_license(out)
    out.write("""
/**
 *
 * AUTOMATICALLY GENERATED FILE.  Edits will be lost on regen.
 *
 * Message-scalar tests for all versions
 */

#include <locitest/test_common.h>
""")
    for version in of_g.of_version_range:
        v_name = loxi_utils.version_to_name(version)
        out.write("""
/**
 * Message-scalar tests for version %s
 */
""" % v_name)
        for cls in of_g.standard_class_order:
            if type_maps.class_is_inheritance_root(cls):
                continue
            if version in of_g.unified[cls]:
                message_scalar_test(out, version, cls)

    out.write("""
int
run_scalar_acc_tests(void)
{
""")
    for version in of_g.of_version_range:
        v_name = loxi_utils.version_to_name(version)
        for cls in of_g.standard_class_order:
            if type_maps.class_is_inheritance_root(cls):
                continue
            if version in of_g.unified[cls]:
                test_name = "%s_%s" % (cls, v_name)
                out.write("    RUN_TEST(%s_scalar);\n" % test_name)

    out.write("    return TEST_PASS;\n}\n");

def message_scalar_test(out, version, cls):
    """
    Generate one test case for the given version and class
    """

    members, member_types = scalar_member_types_get(cls, version)
    length = of_g.base_length[(cls, version)] + of_g.extra_length.get((cls, version), 0)
    v_name = loxi_utils.version_to_name(version)

    out.write("""
static int
test_%(cls)s_%(v_name)s_scalar(void)
{
    %(cls)s_t *obj;

    obj = %(cls)s_new(%(v_name)s);
    TEST_ASSERT(obj != NULL);
    TEST_ASSERT(obj->version == %(v_name)s);
    TEST_ASSERT(obj->length == %(length)d);
    TEST_ASSERT(obj->parent == NULL);
    TEST_ASSERT(obj->object_id == %(u_cls)s);
""" % dict(cls=cls, u_cls=cls.upper(),
           v_name=v_name, length=length, version=version))

    # If this class is a concrete member of an inheritance hierarchy,
    # run the hierarchy's root wire type parser and assert it returns
    # the expected object id.
    ofclass = loxi_globals.unified.class_by_name(cls)
    if ofclass and not ofclass.virtual:
        root = ofclass
        while root.superclass:
            root = root.superclass
        if root.virtual:
            out.write("""
    {
        of_object_id_t object_id;
        %(root_cls)s_wire_object_id_get(obj, &object_id);
        TEST_ASSERT(object_id == %(u_cls)s);
    }
""" % dict(root_cls=root.name, u_cls=cls.upper()))

    if not type_maps.class_is_virtual(cls):
        out.write("""
    if (loci_class_metadata[obj->object_id].wire_length_get != NULL) {
        int length;

        loci_class_metadata[obj->object_id].wire_length_get((of_object_t *)obj, &length);
        TEST_ASSERT(length == %(length)d);
    }

    /* Set up incrementing values for scalar members */
    %(cls)s_%(v_name)s_populate_scalars(obj, 1);

    /* Check values just set */
    TEST_ASSERT(%(cls)s_%(v_name)s_check_scalars(obj, 1) != 0);
""" % dict(cls=cls, u_cls=cls.upper(),
           v_name=v_name, length=length, version=version))

    out.write("""
    %(cls)s_delete(obj);

    /* To do: Check memory */
    return TEST_PASS;
}
""" % dict(cls=cls))

# Get the members and list of scalar types for members of a given class
def scalar_member_types_get(cls, version):
    member_types = []

    if not version in of_g.unified[cls]:
        return ([], [])

    if "use_version" in of_g.unified[cls][version]:
        v = of_g.unified[cls][version]["use_version"]
        members = of_g.unified[cls][v]["members"]
    else:
        members = of_g.unified[cls][version]["members"]
    # Accumulate variables that are supported
    for member in members:
        m_type = member["m_type"]
        m_name = member["name"]
        if (not loxi_utils.type_is_scalar(m_type) or
            ignore_member(cls, version, m_name, m_type)):
            continue
        if not m_type in member_types:
            member_types.append(m_type)

    return (members, member_types)

def scalar_funs_instance(out, cls, version, members, member_types):
    """
    Generate one instance of scalar set/check functions
    """
    out.write("""
/**
 * Populate the scalar values in obj of type %(cls)s,
 * version %(v_name)s
 * @param obj Pointer to an object to populate
 * @param value The seed value to use in populating the object
 * @returns The value after increments for this object's values
 */
int %(cls)s_%(v_name)s_populate_scalars(
    %(cls)s_t *obj, int value) {
""" % dict(cls=cls, v_name=loxi_utils.version_to_name(version)))
    # Declare string types
    for t in member_types:
        out.write("    %s %s;\n" % (t, var_name_map(t)))
    for member in members:
        m_type = member["m_type"]
        m_name = member["name"]
        if (not loxi_utils.type_is_scalar(m_type) or
            ignore_member(cls, version, m_name, m_type)):
            continue
        v_name = var_name_map(m_type);
        out.write("""
    VAR_%(u_type)s_INIT(%(v_name)s, value);
    %(cls)s_%(m_name)s_set(obj, %(v_name)s);
    value += 1;
""" % dict(cls=cls, m_name=m_name, u_type=m_type.upper(), v_name=v_name))
    out.write("""
    return value;
}
""")

    out.write("""
/**
 * Check scalar values in obj of type %(cls)s,
 * version %(v_name)s
 * @param obj Pointer to an object to check
 * @param value Starting value for checking
 * @returns The value after increments for this object's values
 */
int %(cls)s_%(v_name)s_check_scalars(
    %(cls)s_t *obj, int value) {
""" % dict(cls=cls, v_name=loxi_utils.version_to_name(version)))

    for t in member_types:
        out.write("    %s %s;\n" % (t, var_name_map(t)))
    for member in members:
        m_type = member["m_type"]
        m_name = member["name"]
        if (not loxi_utils.type_is_scalar(m_type) or
            ignore_member(cls, version, m_name, m_type)):
            continue
        v_name = var_name_map(m_type);
        out.write("""
    %(cls)s_%(m_name)s_get(obj, &%(v_name)s);
    TEST_ASSERT(VAR_%(u_type)s_CHECK(%(v_name)s, value));
    value += 1;
""" % dict(cls=cls, m_name=m_name, u_type=m_type.upper(), v_name=v_name))

    out.write("""
    return value;
}

""")

def gen_scalar_set_check_funs(out):
    """
    For each object class with scalar members, generate functions that
    set and check their values
    """
    for version in of_g.of_version_range:
        for cls in of_g.standard_class_order:
            (members, member_types) = scalar_member_types_get(cls, version)
            scalar_funs_instance(out, cls, version, members, member_types)


# Helper function to set up a subclass instance for a test
def setup_instance(out, cls, subcls, instance, v_name, version):
    base_type = loxi_utils.list_to_entry_type(cls)
    setup_template = """
    %(subcls)s_init(%(inst)s, %(v_name)s, -1, 1);
    %(cls)s_append_bind(list,
            (%(base_type)s_t *)%(inst)s);
    value = %(subcls)s_%(v_name)s_populate(
        %(inst)s, value);
    cur_len += %(inst)s->length;
    TEST_ASSERT(list->length == cur_len);
"""
    out.write("""
    /* Append two instances of type %s */
""" % subcls)
    for i in range(2):
        out.write(setup_template %
                  dict(inst=instance, subcls=subcls, v_name=v_name,
                       base_type=base_type, cls=cls,
                       version=version))

def check_instance(out, cls, subcls, instance, v_name, version, last):
    check_template = """
    TEST_ASSERT(%(inst)s->object_id == %(elt_name)s);
    value = %(subcls)s_%(v_name)s_check(
        %(inst)s, value);
    TEST_ASSERT(value != 0);
"""
    out.write("\n    /* Check two instances of type %s */" % instance)

    out.write(check_template %
              dict(elt_name=loxi_utils.enum_name(subcls),
                   inst=instance, subcls=subcls,
                   v_name=loxi_utils.version_to_name(version)))
    out.write("""\
    TEST_OK(%(cls)s_next(list, &elt));
""" % dict(cls=cls))

    out.write(check_template %
              dict(elt_name=loxi_utils.enum_name(subcls),
                   inst=instance, subcls=subcls,
                   v_name=loxi_utils.version_to_name(version)))
    if last:
        out.write("""\
    TEST_ASSERT(%(cls)s_next(list, &elt) == OF_ERROR_RANGE);
""" % dict(cls=cls))
    else:
        out.write("""\
    TEST_OK(%(cls)s_next(list, &elt));
""" % dict(cls=cls))

def setup_list_fn(out, version, cls):
    """
    Generate a helper function that populates a list with two
    of each type of subclass it supports
    """
    out.write("""
/**
 * Set up a list of type %(cls)s with two of each type of subclass
 */
int
list_setup_%(cls)s_%(v_name)s(
    %(cls)s_t *list, int value)
{
""" % dict(cls=cls, v_name=loxi_utils.version_to_name(version)))
    base_type = loxi_utils.list_to_entry_type(cls)
    out.write("""
    %(base_type)s_t elt;
    int cur_len = 0;
    (void) elt;
    (void) cur_len;
""" % dict(cls=cls, base_type=base_type))

    sub_classes =  type_maps.sub_class_map(base_type, version)
    sub_classes = [(instance, subcls) for (instance, subcls) in sub_classes if not type_maps.class_is_virtual(subcls)]
    v_name = loxi_utils.version_to_name(version)

    if not type_maps.class_is_virtual(base_type):
        out.write("    /* No subclasses for %s */\n"% base_type)
        out.write("    %s_t *elt_p;\n" % base_type)
        out.write("\n    elt_p = &elt;\n")
    else:
        out.write("    /* Declare pointers for each subclass */\n")
        for instance, subcls in sub_classes:
            out.write("    %s_t *%s;\n" % (subcls, instance))
        out.write("\n    /* Instantiate pointers for each subclass */\n")
        for instance, subcls in sub_classes:
            out.write("    %s = &elt.%s;\n" % (instance, instance))

    if not type_maps.class_is_virtual(base_type): # No inheritance case
        setup_instance(out, cls, base_type, "elt_p", v_name, version)
    else:
        for instance, subcls in sub_classes:
            setup_instance(out, cls, subcls, instance, v_name, version)
    out.write("""

    return value;
}
""")

def check_list_fn(out, version, cls):
    """
    Generate a helper function that checks a list populated by above fn
    """
    out.write("""
/**
 * Check a list of type %(cls)s generated by
 * list_setup_%(cls)s_%(v_name)s
 */
int
list_check_%(cls)s_%(v_name)s(
    %(cls)s_t *list, int value)
{
""" % dict(cls=cls, v_name=loxi_utils.version_to_name(version)))
    base_type = loxi_utils.list_to_entry_type(cls)
    out.write("""
    %(base_type)s_t elt;
    (void) elt;
""" % dict(cls=cls, base_type=base_type))

    sub_classes =  type_maps.sub_class_map(base_type, version)
    sub_classes = [(instance, subcls) for (instance, subcls) in sub_classes if not type_maps.class_is_virtual(subcls)]
    v_name = loxi_utils.version_to_name(version)

    if not type_maps.class_is_virtual(base_type):
        out.write("    /* No subclasses for %s */\n"% base_type)
        out.write("    %s_t *elt_p;\n" % base_type)
        out.write("\n    elt_p = &elt;\n")
    else:
        out.write("    /* Declare pointers for each subclass */\n")
        for instance, subcls in sub_classes:
            out.write("    %s_t *%s;\n" % (subcls, instance))
        out.write("\n    /* Instantiate pointers for each subclass */\n")
        for instance, subcls in sub_classes:
            out.write("    %s = &elt.%s;\n" % (instance, instance))

    if not type_maps.class_is_virtual(base_type) or sub_classes:
        out.write("    TEST_OK(%(cls)s_first(list, &elt));\n" % dict(cls=cls))

    if not type_maps.class_is_virtual(base_type): # No inheritance case
        check_instance(out, cls, base_type, "elt_p", v_name, version, True)
    else:
        count = 0
        for instance, subcls in sub_classes:
            count += 1
            check_instance(out, cls, subcls, instance, v_name,
                           version, count==len(sub_classes))

    out.write("""
    return value;
}
""" % dict(base_type=base_type))

def gen_list_set_check_funs(out):
    for version in of_g.of_version_range:
        for cls in of_g.ordered_list_objects:
            if version in of_g.unified[cls]:
                setup_list_fn(out, version, cls)
                check_list_fn(out, version, cls)

# Maybe: Get a map from list class to parent, mem_name of container

def list_test(out, version, cls):
    out.write("""
static int
test_%(cls)s_%(v_name)s(void)
{
""" % dict(cls=cls, v_name=loxi_utils.version_to_name(version)))
    base_type = loxi_utils.list_to_entry_type(cls)

    out.write("""    %(cls)s_t *list;
    int value = 1;
""" % dict(cls=cls, base_type=base_type))

    out.write("""
    list = %(cls)s_new(%(v_name)s);
    TEST_ASSERT(list != NULL);
    TEST_ASSERT(list->version == %(v_name)s);
    TEST_ASSERT(list->length == 0);
    TEST_ASSERT(list->parent == NULL);
    TEST_ASSERT(list->object_id == %(enum_cls)s);

    value = list_setup_%(cls)s_%(v_name)s(list, value);
    TEST_ASSERT(value != 0);
""" % dict(cls=cls, base_type=base_type, v_name=loxi_utils.version_to_name(version),
           enum_cls=loxi_utils.enum_name(cls)))

    out.write("""
    /* Now check values */
    value = 1;
    value = list_check_%(cls)s_%(v_name)s(list, value);
    TEST_ASSERT(value != 0);
""" % dict(cls=cls, v_name=loxi_utils.version_to_name(version)))

    out.write("""
    %(cls)s_delete(list);

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

def gen_list_test(out, name):
    """
    Generate base line test cases for lists
    @param out The file handle to write to
    """

    loxi_utils.gen_c_copy_license(out)
    out.write("""
/**
 *
 * AUTOMATICALLY GENERATED FILE.  Edits will be lost on regen.
 *
 * Message-scalar tests for all versions
 */

#include <locitest/test_common.h>
""")

    for version in of_g.of_version_range:
        v_name = loxi_utils.version_to_name(version)
        out.write("""
/**
 * Baseline list tests for version %s
 */
""" % v_name)
        for cls in of_g.ordered_list_objects:
            if version in of_g.unified[cls]:
                list_test(out, version, cls)

    out.write("""
int
run_list_tests(void)
{
""")
    for version in of_g.of_version_range:
        v_name = loxi_utils.version_to_name(version)
        for cls in of_g.ordered_list_objects:
            if version in of_g.unified[cls]:
                test_name = "%s_%s" % (cls, v_name)
                out.write("    RUN_TEST(%s);\n" % test_name)

    out.write("\n    return TEST_PASS;\n}\n");

def gen_match_test(out, name):
    """
    Generate baseline tests for match functions
    """

    loxi_utils.gen_c_copy_license(out)
    out.write("""\
/**
 *
 * AUTOMATICALLY GENERATED FILE.  Edits will be lost on regen.
 *
 * Message-scalar tests for all versions
 * @fixme These are mostly hard coded now.
 */

#include <locitest/test_common.h>

static int
test_match_1(void)
{
""")

    for version in of_g.of_version_range:
        out.write("    of_match_v%(v)d_t *m_v%(v)d;\n" % dict(v=version))

    out.write("""\
    of_match_t match;
    int value = 1;
    int idx;
    uint32_t exp_value;

    /* Verify default values for ip mask map */
    for (idx = 0; idx < 64; idx++) {
        exp_value = (idx < 32) ? ~((1 << idx) - 1) : 0;
        TEST_ASSERT(of_ip_index_to_mask(idx) == exp_value);
        if (idx < 32) {
            TEST_ASSERT(of_ip_mask_to_index(exp_value) == idx);
        }
    }
""")

    for version in of_g.of_version_range:
        out.write("""
    /* Create/populate/convert and delete for version %(v_name)s */
    m_v%(version)d = of_match_v%(version)d_new(%(v_name)s);
    TEST_ASSERT(m_v%(version)d != NULL);
    TEST_ASSERT((value = of_match_populate(&match, %(v_name)s, value)) > 0);
    TEST_OK(of_match_to_wire_match_v%(version)d(&match, m_v%(version)d));
    of_match_v%(version)d_delete(m_v%(version)d);
""" % dict(v_name=loxi_utils.version_to_name(version), version=version))

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

    out.write("""
static int
test_match_2(void)
{
""")

    for version in of_g.of_version_range:
        out.write("    of_match_v%(v)d_t *m_v%(v)d;\n" % dict(v=version))

    out.write("""\
    of_match_t match1;
    of_match_t match2;
    int value = 1;
""")

    for version in of_g.of_version_range:
        out.write("""
    TEST_ASSERT((value = of_match_populate(&match1, %(v_name)s, value)) > 0);
    m_v%(version)d = of_match_v%(version)d_new(%(v_name)s);
    TEST_ASSERT(m_v%(version)d != NULL);
    TEST_OK(of_match_to_wire_match_v%(version)d(&match1, m_v%(version)d));
    TEST_OK(of_match_v%(version)d_to_match(m_v%(version)d, &match2));
    TEST_ASSERT(memcmp(&match1, &match2, sizeof(match1)) == 0);
    of_match_v%(version)d_delete(m_v%(version)d);
""" % dict(v_name=loxi_utils.version_to_name(version), version=version))

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

    out.write("""
static int
test_match_3(void)
{
    of_match_t match1;
    of_match_t match2;
    int value = 1;
    of_octets_t octets;
    of_object_storage_t storage;
    memset(&storage, 0, sizeof(storage));
    storage.obj.wbuf = &storage.wbuf;
""")
    for version in of_g.of_version_range:
        out.write("""
    /* Serialize to version %(v_name)s */
    TEST_ASSERT((value = of_match_populate(&match1, %(v_name)s, value)) > 0);
    TEST_ASSERT(of_match_serialize(%(v_name)s, &match1, &octets) ==
        OF_ERROR_NONE);
    storage.obj.wbuf->buf = octets.data;
    storage.obj.wbuf->alloc_bytes = octets.bytes;
    storage.obj.wbuf->current_bytes = octets.bytes;
    TEST_ASSERT(of_match_deserialize(%(v_name)s, &match2, &storage.obj, 0, octets.bytes) ==
        OF_ERROR_NONE);
    TEST_ASSERT(memcmp(&match1, &match2, sizeof(match1)) == 0);
    FREE(octets.data);
""" % dict(v_name=loxi_utils.version_to_name(version), version=version))

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

    out.write("""
int run_match_tests(void)
{
    RUN_TEST(match_1);
    RUN_TEST(match_2);
    RUN_TEST(match_3);
    RUN_TEST(match_utils);

    return TEST_PASS;
}
""")

def gen_msg_test(out, name):
    loxi_utils.gen_c_copy_license(out)
    out.write("""
/**
 *
 * AUTOMATICALLY GENERATED FILE.  Edits will be lost on regen.
 *
 * Message-scalar tests for all versions
 */

#include <locitest/test_common.h>
""")
    for version in of_g.of_version_range:
        for cls in of_g.ordered_messages:
            if not (cls, version) in of_g.base_length:
                continue
            if type_maps.class_is_virtual(cls):
                continue
            bytes = of_g.base_length[(cls, version)] + of_g.extra_length.get((cls, version), 0)
            out.write("""
static int
test_%(cls)s_create_%(v_name)s(void)
{
    %(cls)s_t *obj;
    uint8_t *msg_buf;
    int value;
    of_object_id_t object_id;
    int len;

    obj = %(cls)s_new(%(v_name)s);
    TEST_ASSERT(obj != NULL);
    TEST_ASSERT(obj->version == %(v_name)s);
    TEST_ASSERT(obj->length == %(bytes)d);
    TEST_ASSERT(obj->parent == NULL);
    TEST_ASSERT(obj->object_id == %(enum)s);

    of_header_wire_object_id_get(obj, &object_id);
    TEST_ASSERT(object_id == %(enum)s);

    /* Set up incrementing values for scalar members */
    value = %(cls)s_%(v_name)s_populate_scalars(obj, 1);
    TEST_ASSERT(value != 0);

    len = obj->length;

    /* Grab the underlying buffer from the message */
    of_object_wire_buffer_steal((of_object_t *)obj, &msg_buf);
    TEST_ASSERT(msg_buf != NULL);
    %(cls)s_delete(obj);
    obj = of_object_new_from_message(OF_BUFFER_TO_MESSAGE(msg_buf), len);

    TEST_ASSERT(obj != NULL);

    /* @fixme Set up all message objects (recursively?) */

    value = %(cls)s_%(v_name)s_check_scalars(obj, 1);
    TEST_ASSERT(value != 0);

    %(cls)s_delete(obj);

    return TEST_PASS;
}
""" % dict(cls=cls, version=version, enum=loxi_utils.enum_name(cls),
           v_name=loxi_utils.version_to_name(version), bytes=bytes))

    out.write("""
int
run_message_tests(void)
{
""")
    for version in of_g.of_version_range:
        for cls in of_g.ordered_messages:
            if not (cls, version) in of_g.base_length:
                continue
            if type_maps.class_is_virtual(cls):
                continue
            test_name = "%s_create_%s" % (cls, loxi_utils.version_to_name(version))
            out.write("    RUN_TEST(%s);\n" % test_name)

    out.write("\n    return TEST_PASS;\n}\n");


def gen_list_setup_check(out, cls, version):
    """
    Generate functions that populate and check a list with two
    of each type of subclass it supports
    """
    out.write("""
/**
 * Populate a list of type %(cls)s with two of each type of subclass
 * @param list Pointer to the list to be populated
 * @param value The seed value to use in populating the list
 * @returns The value after increments for this object's values
 */
int
%(cls)s_%(v_name)s_populate(
    %(cls)s_t *list, int value)
{
""" % dict(cls=cls, v_name=loxi_utils.version_to_name(version)))
    base_type = loxi_utils.list_to_entry_type(cls)
    out.write("""
    %(base_type)s_t elt;
    int cur_len = 0;
    (void) elt;
    (void) cur_len;
""" % dict(cls=cls, base_type=base_type))

    sub_classes =  type_maps.sub_class_map(base_type, version)
    sub_classes = [(instance, subcls) for (instance, subcls) in sub_classes if not type_maps.class_is_virtual(subcls)]
    v_name = loxi_utils.version_to_name(version)

    if not type_maps.class_is_virtual(base_type):
        out.write("    /* No subclasses for %s */\n"% base_type)
        out.write("    %s_t *elt_p;\n" % base_type)
        out.write("\n    elt_p = &elt;\n")
    else:
        out.write("    /* Declare pointers for each subclass */\n")
        for instance, subcls in sub_classes:
            out.write("    %s_t *%s;\n" % (subcls, instance))
        out.write("\n    /* Instantiate pointers for each subclass */\n")
        for instance, subcls in sub_classes:
            out.write("    %s = &elt.%s;\n" % (instance, instance))

    if not type_maps.class_is_virtual(base_type): # No inheritance case
        setup_instance(out, cls, base_type, "elt_p", v_name, version)
    else:
        for instance, subcls in sub_classes:
            setup_instance(out, cls, subcls, instance, v_name, version)
    out.write("""
    return value;
}
""")
    out.write("""
/**
 * Check a list of type %(cls)s generated by
 * %(cls)s_%(v_name)s_populate
 * @param list Pointer to the list that was populated
 * @param value Starting value for checking
 * @returns The value after increments for this object's values
 */
int
%(cls)s_%(v_name)s_check(
    %(cls)s_t *list, int value)
{
""" % dict(cls=cls, v_name=loxi_utils.version_to_name(version)))
    base_type = loxi_utils.list_to_entry_type(cls)
    out.write("""
    %(base_type)s_t elt;
    int count = 0;
    int rv;
""" % dict(cls=cls, base_type=base_type))


    sub_classes =  type_maps.sub_class_map(base_type, version)
    sub_classes = [(instance, subcls) for (instance, subcls) in sub_classes if not type_maps.class_is_virtual(subcls)]
    v_name = loxi_utils.version_to_name(version)

    if not type_maps.class_is_virtual(base_type):
        entry_count = 2
        out.write("    /* No subclasses for %s */\n"% base_type)
        out.write("    %s_t *elt_p;\n" % base_type)
        out.write("\n    elt_p = &elt;\n")
    else:
        entry_count = 2 * len(sub_classes) # Two of each type appended
        out.write("    /* Declare pointers for each subclass */\n")
        for instance, subcls in sub_classes:
            out.write("    %s_t *%s;\n" % (subcls, instance))
        out.write("\n    /* Instantiate pointers for each subclass */\n")
        for instance, subcls in sub_classes:
            out.write("    %s = &elt.%s;\n" % (instance, instance))

    if not type_maps.class_is_virtual(base_type) or sub_classes:
        out.write("    TEST_OK(%(cls)s_first(list, &elt));\n" % dict(cls=cls))

    if not type_maps.class_is_virtual(base_type): # No inheritance case
        check_instance(out, cls, base_type, "elt_p", v_name,
                       version, True)
    else:
        count = 0
        for instance, subcls in sub_classes:
            count += 1
            check_instance(out, cls, subcls, instance, v_name,
                           version, count==len(sub_classes))
    out.write("""
""" % dict(base_type=base_type))

    out.write("""
    /* Do an iterate to test the iterator */
    %(u_cls)s_ITER(list, &elt, rv) {
        count += 1;
    }

    TEST_ASSERT(rv == OF_ERROR_RANGE);
    TEST_ASSERT(count == %(entry_count)d);

    /* We shoehorn a test of the dup functions here */
    {
        %(cls)s_t *dup;

        TEST_ASSERT((dup = %(cls)s_dup(list)) != NULL);
        TEST_ASSERT(dup->length == list->length);
        TEST_ASSERT(dup->object_id == list->object_id);
        TEST_ASSERT(dup->version == list->version);
        TEST_ASSERT(MEMCMP(OF_OBJECT_BUFFER_INDEX(dup, 0),
            OF_OBJECT_BUFFER_INDEX(list, 0), list->length) == 0);
        of_object_delete((of_object_t *)dup);

        /* And now for the generic dup function */
        TEST_ASSERT((dup = (%(cls)s_t *)
            of_object_dup(list)) != NULL);
        TEST_ASSERT(dup->length == list->length);
        TEST_ASSERT(dup->object_id == list->object_id);
        TEST_ASSERT(dup->version == list->version);
        TEST_ASSERT(MEMCMP(OF_OBJECT_BUFFER_INDEX(dup, 0),
            OF_OBJECT_BUFFER_INDEX(list, 0), list->length) == 0);
        of_object_delete((of_object_t *)dup);
    }

    return value;
}
""" % dict(cls=cls, u_cls=cls.upper(), entry_count=entry_count))


def gen_class_setup_check(out, cls, version):
    out.write("""
/**
 * Populate all members of an object of type %(cls)s
 * with incrementing values
 * @param obj Pointer to an object to populate
 * @param value The seed value to use in populating the object
 * @returns The value after increments for this object's values
 */

int
%(cls)s_%(v_name)s_populate(
    %(cls)s_t *obj, int value)
{
""" % dict(cls=cls, v_name=loxi_utils.version_to_name(version)))
    members, member_types = loxi_utils.all_member_types_get(cls, version)
    for m_type in member_types:
        if loxi_utils.type_is_scalar(m_type) or m_type in ["of_match_t", "of_octets_t"]:
            out.write("    %s %s;\n" % (m_type, var_name_map(m_type)))
        elif m_type in embedded_subclasses:
            subcls = embedded_subclasses[m_type]
            out.write("    %s_t *%s;\n" % (subcls, var_name_map(m_type)))
        else:
            out.write("    %s *%s;\n" % (m_type, var_name_map(m_type)))
    out.write("""
    /* Run thru accessors after new to ensure okay */
""")
    for member in members:
        m_type = member["m_type"]
        m_name = member["name"]
        if loxi_utils.skip_member_name(m_name):
            continue
        if m_type in embedded_subclasses:
            continue
        if loxi_utils.type_is_scalar(m_type) or m_type in ["of_match_t", "of_octets_t"]:
            out.write("""\
    %(cls)s_%(m_name)s_get(obj, &%(var_name)s);
""" % dict(var_name=var_name_map(m_type), cls=cls, m_name=m_name))
        else:
            sub_cls = m_type[:-2] # Trim _t
            out.write("""\
    {
        %(sub_cls)s_t sub_cls;

        /* Test bind */
        %(cls)s_%(m_name)s_bind(obj, &sub_cls);
    }
""" % dict(var_name=var_name_map(m_type), cls=cls,
           m_name=m_name, sub_cls=sub_cls,
           v_name=loxi_utils.version_to_name(version)))

    out.write("""
    value = %(cls)s_%(v_name)s_populate_scalars(
        obj, value);
    TEST_ASSERT(value != 0);
""" % dict(cls=cls, v_name=loxi_utils.version_to_name(version)))

    for member in members:
        m_type = member["m_type"]
        m_name = member["name"]
        if loxi_utils.type_is_scalar(m_type): # Handled by call to scalar setup
            continue
        if loxi_utils.skip_member_name(m_name):
            continue
        if m_type == "of_match_t":
            out.write("""\
    value = of_match_populate(&%(var_name)s, %(v_name)s, value);
    TEST_ASSERT(value != 0);
    %(cls)s_%(m_name)s_set(
        obj, &%(var_name)s);
""" % dict(cls=cls, var_name=var_name_map(m_type),
           m_name=m_name, v_name=loxi_utils.version_to_name(version)))
        elif m_type == "of_octets_t":
            out.write("""\
    value = of_octets_populate(&%(var_name)s, value);
    TEST_ASSERT(value != 0);
    %(cls)s_%(m_name)s_set(
        obj, &%(var_name)s);
    if (octets.bytes) {
        FREE(octets.data);
    }
""" % dict(var_name=var_name_map(m_type), cls=cls, m_name=m_name))
        elif m_type in embedded_subclasses:
            sub_cls = embedded_subclasses[m_type]
            out.write("""\
    %(var_name)s = %(sub_cls)s_new(%(v_name)s);
    TEST_ASSERT(%(var_name)s != NULL);
    value = %(sub_cls)s_%(v_name)s_populate(
        %(var_name)s, value);
    TEST_ASSERT(value != 0);
    %(cls)s_%(m_name)s_set(
        obj, %(var_name)s);
    %(sub_cls)s_delete(%(var_name)s);
""" % dict(cls=cls, sub_cls=sub_cls, m_name=m_name, m_type=m_type,
           var_name=var_name_map(m_type),
           v_name=loxi_utils.version_to_name(version)))
        else:
            sub_cls = m_type[:-2] # Trim _t
            out.write("""
    %(var_name)s = %(sub_cls)s_new(%(v_name)s);
    TEST_ASSERT(%(var_name)s != NULL);
    value = %(sub_cls)s_%(v_name)s_populate(
        %(var_name)s, value);
    TEST_ASSERT(value != 0);
    %(cls)s_%(m_name)s_set(
        obj, %(var_name)s);
    %(sub_cls)s_delete(%(var_name)s);
""" % dict(cls=cls, sub_cls=sub_cls, m_name=m_name, m_type=m_type,
           var_name=var_name_map(m_type),
           v_name=loxi_utils.version_to_name(version)))

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

    out.write("""
/**
 * Check all members of an object of type %(cls)s
 * populated by the above function
 * @param obj Pointer to an object to check
 * @param value Starting value for checking
 * @returns The value after increments for this object's values
 */

int
%(cls)s_%(v_name)s_check(
    %(cls)s_t *obj, int value)
{
""" % dict(cls=cls, v_name=loxi_utils.version_to_name(version)))
    members, member_types = loxi_utils.all_member_types_get(cls, version)
    for m_type in member_types:
        if loxi_utils.type_is_scalar(m_type): # Handled by call to scalar setup
            continue
        if loxi_utils.type_is_of_object(m_type):
            continue
        out.write("    %s %s;\n" % (m_type, var_name_map(m_type)))
    out.write("""
    value = %(cls)s_%(v_name)s_check_scalars(
        obj, value);
    TEST_ASSERT(value != 0);
""" % dict(cls=cls, v_name=loxi_utils.version_to_name(version)))

    for member in members:
        m_type = member["m_type"]
        m_name = member["name"]
        if loxi_utils.type_is_scalar(m_type): # Handled by call to scalar setup
            continue
        if loxi_utils.skip_member_name(m_name):
            continue
        if m_type == "of_match_t":
            out.write("""\
    %(cls)s_%(m_name)s_get(obj, &%(var_name)s);
    value = of_match_check(&%(var_name)s, %(v_name)s, value);
""" % dict(cls=cls, var_name=var_name_map(m_type), m_name=m_name,
           v_name=loxi_utils.version_to_name(version)))
        elif m_type == "of_octets_t":
            out.write("""\
    %(cls)s_%(m_name)s_get(obj, &%(var_name)s);
    value = of_octets_check(&%(var_name)s, value);
""" % dict(cls=cls, var_name=var_name_map(m_type), m_name=m_name,
           v_name=loxi_utils.version_to_name(version)))
        elif m_type in embedded_subclasses:
            sub_cls = embedded_subclasses[m_type]
            out.write("""
    { /* Use get/delete to access on check */
        %(sub_cls)s_t *%(m_name)s_ptr;

        %(m_name)s_ptr = %(cls)s_%(m_name)s_get(obj);
        TEST_ASSERT(%(m_name)s_ptr != NULL);
        value = %(sub_cls)s_%(v_name)s_check(
            %(m_name)s_ptr, value);
        TEST_ASSERT(value != 0);
        %(sub_cls)s_delete(%(m_name)s_ptr);
    }
""" % dict(cls=cls, sub_cls=sub_cls, m_name=m_name, m_type=m_type,
           var_name=var_name_map(m_type),
           v_name=loxi_utils.version_to_name(version)))
        else:
            sub_cls = m_type[:-2] # Trim _t
            out.write("""
    { /* Use get/delete to access on check */
        %(m_type)s *%(m_name)s_ptr;

        %(m_name)s_ptr = %(cls)s_%(m_name)s_get(obj);
        TEST_ASSERT(%(m_name)s_ptr != NULL);
        value = %(sub_cls)s_%(v_name)s_check(
            %(m_name)s_ptr, value);
        TEST_ASSERT(value != 0);
        %(sub_cls)s_delete(%(m_name)s_ptr);
    }
""" % dict(cls=cls, sub_cls=sub_cls, m_name=m_name, m_type=m_type,
           var_name=var_name_map(m_type),
           v_name=loxi_utils.version_to_name(version)))

    out.write("""
    /* We shoehorn a test of the dup functions here */
    {
        %(cls)s_t *dup;

        TEST_ASSERT((dup = %(cls)s_dup(obj)) != NULL);
        TEST_ASSERT(dup->length == obj->length);
        TEST_ASSERT(dup->object_id == obj->object_id);
        TEST_ASSERT(dup->version == obj->version);
        TEST_ASSERT(MEMCMP(OF_OBJECT_BUFFER_INDEX(dup, 0),
            OF_OBJECT_BUFFER_INDEX(obj, 0), obj->length) == 0);
        of_object_delete((of_object_t *)dup);

        /* And now for the generic dup function */
        TEST_ASSERT((dup = (%(cls)s_t *)
            of_object_dup(obj)) != NULL);
        TEST_ASSERT(dup->length == obj->length);
        TEST_ASSERT(dup->object_id == obj->object_id);
        TEST_ASSERT(dup->version == obj->version);
        TEST_ASSERT(MEMCMP(OF_OBJECT_BUFFER_INDEX(dup, 0),
            OF_OBJECT_BUFFER_INDEX(obj, 0), obj->length) == 0);
        of_object_delete((of_object_t *)dup);
    }

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

def unified_accessor_test_case(out, cls, version):
    """
    Generate one test case for the given version and class
    """

    members, member_types = scalar_member_types_get(cls, version)
    length = of_g.base_length[(cls, version)] + of_g.extra_length.get((cls, version), 0)
    v_name = loxi_utils.version_to_name(version)

    out.write("""
static int
test_%(cls)s_%(v_name)s(void)
{
    %(cls)s_t *obj;
    obj = %(cls)s_new(%(v_name)s);
    TEST_ASSERT(obj != NULL);
    TEST_ASSERT(obj->version == %(v_name)s);
    TEST_ASSERT(obj->length == %(length)d);
    TEST_ASSERT(obj->parent == NULL);
    TEST_ASSERT(obj->object_id == %(u_cls)s);
""" % dict(cls=cls, u_cls=cls.upper(),
           v_name=v_name, length=length, version=version))
    if (not type_maps.class_is_virtual(cls)) or loxi_utils.class_is_list(cls):
        out.write("""
    if (loci_class_metadata[obj->object_id].wire_length_get != NULL) {
        int length;

        loci_class_metadata[obj->object_id].wire_length_get((of_object_t *)obj, &length);
        TEST_ASSERT(length == %(length)d);
    }
    if (loci_class_metadata[obj->object_id].wire_type_get != NULL) {
        of_object_id_t obj_id;

        loci_class_metadata[obj->object_id].wire_type_get((of_object_t *)obj, &obj_id);
        TEST_ASSERT(obj_id == %(u_cls)s);
    }

    /* Set up incrementing values for members */
    TEST_ASSERT(%(cls)s_%(v_name)s_populate(
        obj, 1) != 0);

    /* Check values just set */
    TEST_ASSERT(%(cls)s_%(v_name)s_check(
        obj, 1) != 0);
""" % dict(cls=cls, u_cls=cls.upper(),
           v_name=v_name, length=length, version=version))

    out.write("""
    %(cls)s_delete(obj);

    /* To do: Check memory */
    return TEST_PASS;
}
""" % dict(cls=cls))


def gen_unified_accessor_funs(out):
    for version in of_g.of_version_range:
        for cls in of_g.standard_class_order:
            if not loxi_utils.class_in_version(cls, version):
                continue
            if type_maps.class_is_inheritance_root(cls):
                continue
            elif loxi_utils.class_is_list(cls):
                gen_list_setup_check(out, cls, version)
            else:
                gen_class_setup_check(out, cls, version)

def gen_unified_accessor_tests(out, name):
    loxi_utils.gen_c_copy_license(out)
    out.write("""
/**
 *
 * AUTOMATICALLY GENERATED FILE.  Edits will be lost on regen.
 *
 * Unified simple class instantiation tests for all versions
 */

#include <locitest/test_common.h>
""")
    for version in of_g.of_version_range:
        for cls in of_g.standard_class_order:
            if not loxi_utils.class_in_version(cls, version):
                continue
            if type_maps.class_is_inheritance_root(cls):
                continue
            unified_accessor_test_case(out, cls, version)

    out.write("""
int
run_unified_accessor_tests(void)
{
""")
    for version in of_g.of_version_range:
        v_name = loxi_utils.version_to_name(version)
        for cls in of_g.standard_class_order:
            if not loxi_utils.class_in_version(cls, version):
                continue
            if type_maps.class_is_inheritance_root(cls):
                continue
            test_name = "%s_%s" % (cls, v_name)
            out.write("    RUN_TEST(%s);\n" % test_name)

    out.write("    return TEST_PASS;\n}\n");



################################################################
#
# Object duplication functions
#
# These exercise the accessors to create duplicate objects.
# They are used in the LOCI test shim which sits in an OF
# protocol stream.
#
# TODO
# Resolve version stuff
# Complete list dup

def gen_dup_list(out, cls, version):
    ver_name = loxi_utils.version_to_name(version)
    elt_type = loxi_utils.list_to_entry_type(cls)
    out.write("""
/**
 * Duplicate a list of type %(cls)s
 * using accessor functions
 * @param src Pointer to object to be duplicated
 * @returns A new object of type %(cls)s.
 *
 * The caller is responsible for deleting the returned value
 */
%(cls)s_t *
%(cls)s_%(ver_name)s_dup(
    %(cls)s_t *src)
{
    %(elt_type)s_t src_elt;
    %(elt_type)s_t *dst_elt;
    int rv;
    %(cls)s_t *dst;

    if ((dst = %(cls)s_new(src->version)) == NULL) {
        return NULL;
    }
""" % dict(elt_type=elt_type, cls=cls, ver_name=ver_name))

    out.write("""
    %(u_cls)s_ITER(src, &src_elt, rv) {
        if ((dst_elt = %(elt_type)s_%(ver_name)s_dup(&src_elt)) == NULL) {
            of_object_delete((of_object_t *)dst);
            return NULL;
        }
        _TRY_FREE(%(cls)s_append(dst, dst_elt),
            dst, NULL);
        of_object_delete((of_object_t *)dst_elt);
    }

    return dst;
}
""" % dict(u_cls=cls.upper(), elt_type=elt_type, cls=cls, ver_name=ver_name))


def gen_dup_inheritance(out, cls, version):
    ver_name = loxi_utils.version_to_name(version)
    out.write("""
/**
 * Duplicate a super class object of type %(cls)s
 * @param src Pointer to object to be duplicated
 * @returns A new object of type %(cls)s.
 *
 * The caller is responsible for deleting the returned value
 */
%(cls)s_t *
%(cls)s_%(ver_name)s_dup(
    %(cls)s_t *src)
{
""" % dict(cls=cls, ver_name=ver_name))

    # For each subclass, check if this is an instance of that subclass
    sub_classes = type_maps.sub_class_map(cls, version)
    for (_, sub_cls) in sub_classes:
        sub_enum = sub_cls.upper()
        out.write("""
    if (src->header.object_id == %(sub_enum)s) {
        return (%(cls)s_t *)%(sub_cls)s_%(ver_name)s_dup(
            (of_object_t *)src);
    }
""" % dict(sub_cls=sub_cls, ver_name=ver_name, sub_enum=sub_enum, cls=cls))

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


def gen_dup_cls(out, cls, version):
    """
    Generate duplication routine for class cls
    """
    ver_name = loxi_utils.version_to_name(version)

    out.write("""
/**
 * Duplicate an object of type %(cls)s
 * using accessor functions
 * @param src Pointer to object to be duplicated
 * @returns A new object of type %(cls)s.
 *
 * The caller is responsible for deleting the returned value
 */
%(cls)s_t *
%(cls)s_%(ver_name)s_dup(
    %(cls)s_t *src)
{
    %(cls)s_t *dst;
""" % dict(cls=cls, ver_name=ver_name))

    # Get members and types for the class
    members, member_types = loxi_utils.all_member_types_get(cls, version)

    # Add declarations for each member type
    for m_type in member_types:
        if loxi_utils.type_is_scalar(m_type) or m_type in ["of_match_t", "of_octets_t"]:
            # Declare instance of these
            out.write("    %s %s;\n" % (m_type, var_name_map(m_type)))
        elif m_type in embedded_subclasses:
            sub_cls = embedded_subclasses[m_type]
            out.write("""
    %(sub_cls)s_t src_%(v_name)s;
    %(sub_cls)s_t *dst_%(v_name)s;
""" % dict(v_name=var_name_map(m_type), sub_cls=sub_cls))
        else:
            out.write("""
    %(m_type)s src_%(v_name)s;
    %(m_type)s *dst_%(v_name)s;
"""  % dict(m_type=m_type, v_name=var_name_map(m_type)))

    out.write("""
    if ((dst = %(cls)s_new(src->version)) == NULL) {
        return NULL;
    }
""" % dict(cls=cls))

    for member in members:
        m_type = member["m_type"]
        m_name = member["name"]
        if loxi_utils.skip_member_name(m_name):
            continue
        if loxi_utils.type_is_scalar(m_type): # Handled by call to scalar setup
            out.write("""
    %(cls)s_%(m_name)s_get(src, &%(v_name)s);
    %(cls)s_%(m_name)s_set(dst, %(v_name)s);
""" % dict(cls=cls, m_name=m_name, v_name=var_name_map(m_type)))
        elif m_type in ["of_match_t", "of_octets_t"]:
            out.write("""
    %(cls)s_%(m_name)s_get(src, &%(v_name)s);
    %(cls)s_%(m_name)s_set(dst, &%(v_name)s);
""" % dict(cls=cls, m_name=m_name, v_name=var_name_map(m_type)))
        elif m_type in embedded_subclasses:
            sub_cls = embedded_subclasses[m_type]
            out.write("""
    %(cls)s_%(m_name)s_bind(
        src, &src_%(v_name)s);
    dst_%(v_name)s = %(sub_cls)s_%(ver_name)s_dup(&src_%(v_name)s);
    if (dst_%(v_name)s == NULL) {
        %(cls)s_delete(dst);
        return NULL;
    }
    %(cls)s_%(m_name)s_set(dst, dst_%(v_name)s);
    %(sub_cls)s_delete(dst_%(v_name)s);
""" % dict(sub_cls=sub_cls, cls=cls, m_name=m_name,
           v_name=var_name_map(m_type), ver_name=ver_name))
        else:
            sub_cls = m_type[:-2] # Trim _t
            out.write("""
    %(cls)s_%(m_name)s_bind(
        src, &src_%(v_name)s);
    dst_%(v_name)s = %(sub_cls)s_%(ver_name)s_dup(&src_%(v_name)s);
    if (dst_%(v_name)s == NULL) {
        %(cls)s_delete(dst);
        return NULL;
    }
    %(cls)s_%(m_name)s_set(dst, dst_%(v_name)s);
    %(sub_cls)s_delete(dst_%(v_name)s);
""" % dict(sub_cls=sub_cls, cls=cls, m_name=m_name,
           v_name=var_name_map(m_type), ver_name=ver_name))

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

def gen_version_dup(out=sys.stdout):
    """
    Generate duplication routines for each object type
    """
    out.write("""
/* Special try macro for duplicating */
#define _TRY_FREE(op, obj, rv) do { \\
        int _rv;                                                             \\
        if ((_rv = (op)) < 0) {                                              \\
            LOCI_LOG_ERROR("ERROR %d at %s:%d\\n", _rv, __FILE__, __LINE__);    \\
            of_object_delete((of_object_t *)(obj));                          \\
            return (rv);                                                     \\
        }                                                                    \\
    } while (0)
""")

    for version in of_g.of_version_range:
        for cls in of_g.standard_class_order:
            if not loxi_utils.class_in_version(cls, version):
                continue
            if type_maps.class_is_inheritance_root(cls):
                gen_dup_inheritance(out, cls, version)
            elif loxi_utils.class_is_list(cls):
                gen_dup_list(out, cls, version)
            else:
                gen_dup_cls(out, cls, version)

def gen_dup(out=sys.stdout):
    """
    Generate non-version specific duplication routines for each object type
    """

    for cls in of_g.standard_class_order:
        out.write("""
%(cls)s_t *
%(cls)s_dup(
    %(cls)s_t *src)
{
""" % dict(cls=cls))
        for version in of_g.of_version_range:
            if not loxi_utils.class_in_version(cls, version):
                continue
            hdr = "header." if type_maps.class_is_inheritance_root(cls) else ""

            ver_name = loxi_utils.version_to_name(version)
            out.write("""
    if (src->%(hdr)sversion == %(ver_name)s) {
        return %(cls)s_%(ver_name)s_dup(src);
    }
""" % dict(cls=cls, ver_name=ver_name, hdr=hdr))

        out.write("""
    /* Class not supported in given version */
    return NULL;
}
""")

def dup_c_gen(out, name):
    """
    Generate the C file for duplication functions
    """
    loxi_utils.gen_c_copy_license(out)
    out.write("""\
/*
 * Duplication functions for all OF objects
 *
 * AUTOMATICALLY GENERATED FILE.  Edits will be lost on regen.
 *
 * These are test functions for exercising accessors.  You can call
 * of_object_dup for an efficient duplication.
 */

#define DISABLE_WARN_UNUSED_RESULT
#include "loci_log.h"
#include <locitest/of_dup.h>

""")

    gen_version_dup(out)
    gen_dup(out)


def dup_h_gen(out, name):
    """
    Generate the header file for duplication functions
    """

    loxi_utils.gen_c_copy_license(out)
    out.write("""
/*
 * Duplication function header file
 *
 * AUTOMATICALLY GENERATED FILE.  Edits will be lost on regen.
 */

#if !defined(_OF_DUP_H_)
#define _OF_DUP_H_

#include <loci/loci.h>
""")

    for cls in of_g.standard_class_order:
        out.write("""
extern %(cls)s_t *
    %(cls)s_dup(
        %(cls)s_t *src);
""" % dict(cls=cls))

    for version in of_g.of_version_range:
        for cls in of_g.standard_class_order:
            if not loxi_utils.class_in_version(cls, version):
                continue
            ver_name = loxi_utils.version_to_name(version)
            out.write("""
extern %(cls)s_t *
    %(cls)s_%(ver_name)s_dup(
        %(cls)s_t *src);
""" % dict(cls=cls, ver_name=ver_name))

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

def gen_log_test(out):
    """
    Generate test for obj log calls

    Define a trivial handler for object logging; call all obj log fns
    """
    out.write("""

/**
 * Test object dump functions
 */

int
test_dump_objs(void)
{
    of_object_t *obj;

    FILE *out = fopen("/dev/null", "w");

    /* Call each obj dump function */
""")
    for version in of_g.of_version_range:
        for j, cls in enumerate(of_g.all_class_order):
            if not loxi_utils.class_in_version(cls, version):
                continue
            if type_maps.class_is_inheritance_root(cls):
                continue
            if cls == "of_bsn_virtual_port_create_request": # test q_in_q
                out.write("""
    obj = (of_object_t *)%(cls)s_new(%(version)s);
    {
        of_object_t *vport = of_bsn_vport_q_in_q_new(%(version)s);
        %(cls)s_vport_set(obj, vport);
        of_object_delete(vport);
    }
    of_object_dump((loci_writer_f)fprintf, out, obj);
    of_object_delete(obj);
""" % dict(cls=cls, version=of_g.of_version_wire2name[version]))
            else:
                out.write("""
    obj = (of_object_t *)%(cls)s_new(%(version)s);
    of_object_dump((loci_writer_f)fprintf, out, obj);
    of_object_delete(obj);
""" % dict(cls=cls, version=of_g.of_version_wire2name[version]))

    out.write("""
    fclose(out);
    return TEST_PASS;
}
""")

def gen_ident_tests(out):
    """
    Generate tests for identifiers

    For all idents, instantiate, test version supported macros
    For flags, set it, test it, clear it, test it.
    """
    out.write("""
/**
 * Test cases for all flag accessor macros
 * These only test self consistency (and that they compile)
 */
int
test_ident_macros(void)
{
    int value __attribute__((unused));
    uint32_t flags;

""")

    for ident, info in of_g.identifiers.items():
        if not identifiers.defined_versions_agree(of_g.identifiers,
                                                  of_g.target_version_list,
                                                  ident):
            # @fixme
            continue
        out.write("    value = %s;\n" % ident)
        for version in of_g.target_version_list:
            if version in info["values_by_version"].keys():
                out.write("    TEST_ASSERT(%s_SUPPORTED(%s));\n" %
                          (ident, of_g.of_version_wire2name[version]))
            else:
                out.write("    TEST_ASSERT(!%s_SUPPORTED(%s));\n" %
                          (ident, of_g.of_version_wire2name[version]))
        if flags.ident_is_flag(ident):
            # Grab first supported version
            for version in info["values_by_version"]:
                break
            out.write("""
    flags = 0;
    %(ident)s_SET(flags, %(ver_name)s);
    TEST_ASSERT(flags == %(ident)s_BY_VERSION(%(ver_name)s));
    TEST_ASSERT(%(ident)s_TEST(flags, %(ver_name)s));
    %(ident)s_CLEAR(flags, %(ver_name)s);
    TEST_ASSERT(flags == 0);
    TEST_ASSERT(!%(ident)s_TEST(flags, %(ver_name)s));
""" % dict(ident=ident, ver_name=of_g.of_version_wire2name[version]))

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

def gen_datafiles_tests(out, name):
    tests = []
    for filename in test_data.list_files():
        data = test_data.read(filename)
        if not 'c' in data:
            continue
        name = filename[:-5].replace("/", "_")
        tests.append(dict(name=name,
                          filename=filename,
                          c=data['c'],
                          binary=data['binary']))

    util.render_template(out, "test_data.c", tests=tests)
