# 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 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
import util
import test_data

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_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",
        # BSN extensions
        of_bsn_vport_q_in_q_t="vport",
        )

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

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

/* 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 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)] + 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 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)] + 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;
    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)] + 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 (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;
}
""")

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)
