# 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",
        of_bitmap_128_t="bitmap_128",
        )

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

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

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

    if (cls in ["of_bsn_lacp_stats_request", "of_bsn_lacp_stats_reply"] 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;
    }

    /* Restrict values according to masks */
    of_match_values_mask(match);
    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)
    sub_classes = [(instance, subcls) for (instance, subcls) in sub_classes if not type_maps.class_is_virtual(subcls)]
    v_name = loxi_utils.version_to_name(version)

    if 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)
    sub_classes = [(instance, subcls) for (instance, subcls) in sub_classes if not type_maps.class_is_virtual(subcls)]
    v_name = loxi_utils.version_to_name(version)

    if 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
            if type_maps.class_is_virtual(cls):
                continue
            bytes = of_g.base_length[(cls, version)] + of_g.extra_length.get((cls, version), 0)
            out.write("""
static int
test_%(cls)s_create_%(v_name)s(void)
{
    %(cls)s_t *obj;
    uint8_t *msg_buf;
    int value;
    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
            if type_maps.class_is_virtual(cls):
                continue
            test_name = "%s_create_%s" % (cls, loxi_utils.version_to_name(version))
            out.write("    RUN_TEST(%s);\n" % test_name)

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


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

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

    if 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)
    sub_classes = [(instance, subcls) for (instance, subcls) in sub_classes if not type_maps.class_is_virtual(subcls)]
    v_name = loxi_utils.version_to_name(version)

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