# 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 (not supported on Mac OS X).

"""

import sys
import of_g
import loxi_front_end.match as match
import loxi_front_end.flags as flags
from generic_utils import *
import loxi_front_end.type_maps as type_maps
import loxi_utils.loxi_utils as loxi_utils
import loxi_front_end.identifiers as identifiers

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

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

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

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.
    """
    # This will probably need more granularity as more extensions are added
    if (type_maps.class_is_extension(cls, version) and (
            m_name == "experimenter" or
            m_name == "subtype")):
        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;
""")

    for key, entry in match.of_match_members.items():
        out.write("""
    if (!(of_match_incompat[version] &
            OF_OXM_BIT(OF_OXM_INDEX_%(ku)s))) {
        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("""
    if (value % 2) {
        /* Sometimes set ipv4 addr masks to non-exact */
        match->masks.ipv4_src = 0xffff0000;
        match->masks.ipv4_dst = 0xfffff800;
    }
    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_setup_from_add_tests(void);

extern int run_validator_tests(void);

extern int run_list_limits_tests(void);

extern int test_ext_objs(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 cls in type_maps.inheritance_map:
                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 cls in type_maps.inheritance_map:
                continue

            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>

#if !defined(__APPLE__)
#include <mcheck.h>
#define MCHECK_INIT mcheck(NULL)
#else /* mcheck not available under OS X */
#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 cls in type_maps.inheritance_map:
                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 cls in type_maps.inheritance_map:
                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)]
    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 not type_maps.class_is_virtual(cls):
        out.write("""
    if (obj->wire_length_get != NULL) {
        int length;

        obj->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, inst_len, 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, inst_len=inst_len,
                       version=version))

def check_instance(out, cls, subcls, instance, v_name, inst_len, version, last):
    check_template = ""
    if inst_len >= 0:
        check_template = """
    TEST_ASSERT(%(inst)s->length == %(inst_len)d);
    if (%(inst)s->wire_length_get != NULL) {
        int length;

        %(inst)s->wire_length_get(
            (of_object_t *)&elt, &length);
        TEST_ASSERT(length == %(inst_len)d);
    }
"""
    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_len=inst_len,
                   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_len=inst_len,
                   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;
""" % dict(cls=cls, base_type=base_type))

    sub_classes =  type_maps.sub_class_map(base_type, version)
    v_name = loxi_utils.version_to_name(version)

    if len(sub_classes) == 0:
        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 len(sub_classes) == 0: # No inheritance case
        inst_len = loxi_utils.base_type_to_length(base_type, version)
        setup_instance(out, cls, base_type, "elt_p", v_name, inst_len, version)
    else:
        for instance, subcls in sub_classes:
            inst_len = of_g.base_length[(subcls, version)]
            setup_instance(out, cls, subcls, instance, v_name, inst_len, 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;
""" % dict(cls=cls, base_type=base_type))

    sub_classes =  type_maps.sub_class_map(base_type, version)
    v_name = loxi_utils.version_to_name(version)

    if len(sub_classes) == 0:
        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))

    out.write("    TEST_OK(%(cls)s_first(list, &elt));\n" % dict(cls=cls))
    if len(sub_classes) == 0: # No inheritance case
        if loxi_utils.class_is_var_len(base_type, version):
            inst_len = -1
        else:
            inst_len = loxi_utils.base_type_to_length(base_type, version)
        check_instance(out, cls, base_type, "elt_p", v_name, inst_len,
                       version, True)
    else:
        count = 0
        for instance, subcls in sub_classes:
            count += 1
            if loxi_utils.class_is_var_len(subcls, version):
                inst_len = -1
            else:
                inst_len = of_g.base_length[(subcls, version)]
            check_instance(out, cls, subcls, instance, v_name, inst_len,
                           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 cls in type_maps.inheritance_map:
                continue

            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 cls in type_maps.inheritance_map:
                continue
            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 cls in type_maps.inheritance_map:
                continue
            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)
{
    of_match_v1_t *m_v1;
    of_match_v2_t *m_v2;
    of_match_v3_t *m_v3;
    of_match_v4_t *m_v4;
    of_match_t match;
    int value = 1;
    int idx;
    uint32_t exp_value;

    /* Verify default values for ip mask map */
    for (idx = 0; idx < OF_IP_MASK_MAP_COUNT; 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);
        }
    }

    TEST_ASSERT(of_ip_mask_map_set(17, 0xabcdef00) == OF_ERROR_NONE);
    TEST_ASSERT(of_ip_mask_to_index(0xabcdef00) == 17);
    TEST_ASSERT(of_ip_index_to_mask(17) == 0xabcdef00);

    TEST_ASSERT(of_ip_mask_map_set(62, 0xabcdefff) == OF_ERROR_NONE);
    TEST_ASSERT(of_ip_mask_to_index(0xabcdefff) == 62);
    TEST_ASSERT(of_ip_index_to_mask(62) == 0xabcdefff);

    /* Test re-init */
    of_ip_mask_map_init();
    for (idx = 0; idx < OF_IP_MASK_MAP_COUNT; 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)
{
    of_match_v1_t *m_v1;
    of_match_v2_t *m_v2;
    of_match_v3_t *m_v3;
    of_match_v3_t *m_v4;
    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;
""")
    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);
    TEST_ASSERT(of_match_deserialize(%(v_name)s, &match2, &octets) ==
        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
            bytes = of_g.base_length[(cls, version)]
            out.write("""
static int
test_%(cls)s_create_%(v_name)s(void)
{
    %(cls)s_t *obj;
    uint8_t *msg_buf;
    int value;
    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);

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

    /* Grab the underlying buffer from the message */
    len = obj->length;
    of_object_wire_buffer_steal((of_object_t *)obj, &msg_buf);
    TEST_ASSERT(msg_buf != NULL);
    %(cls)s_delete(obj);
    /* TODO:  */
    TEST_ASSERT(of_message_to_object_id(msg_buf, len) == %(enum)s);
    obj = %(cls)s_new_from_message(OF_BUFFER_TO_MESSAGE(msg_buf));

    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
            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;
""" % dict(cls=cls, base_type=base_type))

    sub_classes =  type_maps.sub_class_map(base_type, version)
    v_name = loxi_utils.version_to_name(version)

    if len(sub_classes) == 0:
        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 type_maps.class_is_virtual(base_type):
#         out.write("""\
#     TEST_OK(%(base_type)s_header_init(
#         (%(base_type)s_header_t *)&elt, %(v_name)s, -1, 1));
# """ % dict(base_type=base_type, v_name=loxi_utils.version_to_name(version)))
#     else:
#         out.write("""\
#     TEST_OK(%(base_type)s_init(&elt, %(v_name)s, -1, 1));
# """ % dict(base_type=base_type, v_name=loxi_utils.version_to_name(version)))

    if len(sub_classes) == 0: # No inheritance case
        inst_len = loxi_utils.base_type_to_length(base_type, version)
        setup_instance(out, cls, base_type, "elt_p", v_name, inst_len, version)
    else:
        for instance, subcls in sub_classes:
            inst_len = of_g.base_length[(subcls, version)]
            setup_instance(out, cls, subcls, instance, v_name,
                           inst_len, 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)
    v_name = loxi_utils.version_to_name(version)

    if len(sub_classes) == 0:
        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))

    out.write("    TEST_OK(%(cls)s_first(list, &elt));\n" % dict(cls=cls))
    if len(sub_classes) == 0: # No inheritance case
        if loxi_utils.class_is_var_len(base_type, version):
            inst_len = -1
        else:
            inst_len = loxi_utils.base_type_to_length(base_type, version)
        check_instance(out, cls, base_type, "elt_p", v_name, inst_len,
                       version, True)
    else:
        count = 0
        for instance, subcls in sub_classes:
            count += 1
            if loxi_utils.class_is_var_len(subcls, version):
                inst_len = -1
            else:
                inst_len = of_g.base_length[(subcls, version)]
            check_instance(out, cls, subcls, instance, v_name, inst_len,
                           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)))
        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 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))
        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)))
        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)]
    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 (obj->wire_length_get != NULL) {
        int length;

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

        obj->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 cls in type_maps.inheritance_map:
                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 cls in type_maps.inheritance_map:
                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 cls in type_maps.inheritance_map:
                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
    version_classes = type_maps.inheritance_data[cls][version]
    for sub_cls in version_classes:
        sub_enum = (cls + "_" + sub_cls).upper()
        out.write("""
    if (src->header.object_id == %(sub_enum)s) {
        return (%(cls)s_t *)%(cls)s_%(sub_cls)s_%(ver_name)s_dup(
            &src->%(sub_cls)s);
    }
""" % 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)))
        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)))
        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 cls in type_maps.inheritance_map:
                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 cls in type_maps.inheritance_map 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 cls in type_maps.inheritance_map:
                continue
            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;
}
""")

