# 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 Generate wire to generic match conversion functions
#
# @fixme This has lots of C specific code that should be moved into c_gen

# of_match_to_wire_match(match, wire_match)
# of_wire_match_to_match(wire_match, match)
#    Version is taken from the source in each case
#
# name
# type
# conditions
# v3 ident
# takes mask

import sys
import of_g
import loxi_front_end.oxm as oxm
import loxi_front_end.match as match
import c_code_gen

def match_c_top_matter(out, name):
    """
    Generate top matter for match C file

    @param name The name of the output file
    @param out The output file object
    """
    c_code_gen.common_top_matter(out, name)
    out.write("#include \"loci_log.h\"\n")
    out.write("#include <loci/loci.h>\n")

def match_h_top_matter(out, name):
    """
    Generate top matter for the C file

    @param name The name of the output file
    @param ih_name The name of the internal header file
    @param out The output file object
    """
    c_code_gen.common_top_matter(out, name)
    out.write("""
#include <loci/loci_base.h>
""")

def gen_declarations(out):
    out.write("""
/*
 * Match serialize/deserialize declarations
 * Wire match conversion function declarations
 */
extern int of_match_serialize(of_version_t version, of_match_t *match,
                              of_octets_t *octets);
extern int of_match_deserialize(of_version_t version, of_match_t *match,
                                of_octets_t *octets);
extern int of_match_v1_to_match(of_match_v1_t *src, of_match_t *dst);
extern int of_match_v2_to_match(of_match_v2_t *src, of_match_t *dst);
extern int of_match_v3_to_match(of_match_v3_t *src, of_match_t *dst);
extern int of_match_to_wire_match_v1(of_match_t *src, of_match_v1_t *dst);
extern int of_match_to_wire_match_v2(of_match_t *src, of_match_v2_t *dst);
extern int of_match_to_wire_match_v3(of_match_t *src, of_match_v3_t *dst);
""")

def gen_v4_match_compat(out):
    """
    Code for coercing version 1.3 matches to 1.2 matches

    @FIXME This is a stopgap and needs to get cleaned up.
    """
    out.write("""
/**
 * Definitions to coerce v4 match (version 1.3) to v3 matches
 * (version 1.2).
 * @FIXME This is a stopgap and needs to get cleaned up.
 */
#define of_match_v4_t of_match_v3_t
#define of_match_v4_init of_match_v3_init
#define of_match_v4_new of_match_v3_new
#define of_match_v4_to_match of_match_v3_to_match
#define of_match_to_wire_match_v4 of_match_to_wire_match_v3
#define of_match_v4_delete of_match_v3_delete
""")

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

/**
 * Definitions for wildcard macros for OF_VERSION_1_0
 */

""")
    for key in match.of_v1_keys:
        entry = match.of_match_members[key]
        if "v1_wc_shift" in entry:
            if key in ["ipv4_src", "ipv4_dst"]:
                out.write("""
#define OF_MATCH_V1_WC_%(ku)s_SHIFT %(val)d
#define OF_MATCH_V1_WC_%(ku)s_MASK (0x3f << %(val)d)
#define OF_MATCH_V1_WC_%(ku)s_CLEAR(wc) ((wc) &= ~(0x3f << %(val)d))
#define OF_MATCH_V1_WC_%(ku)s_SET(wc, value) do {   \\
        OF_MATCH_V1_WC_%(ku)s_CLEAR(wc); \\
        ((wc) |= (((value) & 0x3f) << %(val)d)); \\
    } while (0)
#define OF_MATCH_V1_WC_%(ku)s_TEST(wc) ((wc) & (0x3f << %(val)d))
#define OF_MATCH_V1_WC_%(ku)s_GET(wc) (((wc) >> %(val)d) & 0x3f)
""" % dict(ku=key.upper(), val=entry["v1_wc_shift"]))
            else:
                out.write("""
#define OF_MATCH_V1_WC_%(ku)s_SHIFT %(val)d
#define OF_MATCH_V1_WC_%(ku)s_MASK (1 << %(val)d)
#define OF_MATCH_V1_WC_%(ku)s_SET(wc) ((wc) |= (1 << %(val)d))
#define OF_MATCH_V1_WC_%(ku)s_CLEAR(wc) ((wc) &= ~(1 << %(val)d))
#define OF_MATCH_V1_WC_%(ku)s_TEST(wc) ((wc) & (1 << %(val)d))
""" % dict(ku=key.upper(), val=entry["v1_wc_shift"]))

    out.write("""

/**
 * Definitions for wildcard macros for OF_VERSION_1_1
 */
""")

    for key in sorted(match.of_v2_keys):
        entry = match.of_match_members[key]
        if "v2_wc_shift" in entry:
            out.write("""
#define OF_MATCH_V2_WC_%(ku)s_SHIFT %(val)d
#define OF_MATCH_V2_WC_%(ku)s_MASK (1 << %(val)d)
#define OF_MATCH_V2_WC_%(ku)s_SET(wc) ((wc) |= (1 << %(val)d))
#define OF_MATCH_V2_WC_%(ku)s_CLEAR(wc) ((wc) &= ~(1 << %(val)d))
#define OF_MATCH_V2_WC_%(ku)s_TEST(wc) ((wc) & (1 << %(val)d))
""" % dict(ku=key.upper(), val=entry["v2_wc_shift"]))


def gen_match_struct(out=sys.stdout):
    out.write("/* Unified, flat OpenFlow match structure based on OF 1.2 */\n")
    out.write("typedef struct of_match_fields_s {\n")
    out.write("    /* Version 1.2 is used for field names */\n")
    for name in match.match_keys_sorted:
        entry = match.of_match_members[name]
        out.write("    %-20s %s;\n" % (entry["m_type"], entry["name"]))
    out.write("""
} of_match_fields_t;

/**
 * @brief The LOCI match structure.
 */

typedef struct of_match_s {
    of_version_t version;
    of_match_fields_t fields;
    of_match_fields_t masks;
} of_match_t;

/**
 * IP Mask map.  IP maks wildcards from OF 1.0 are interpretted as
 * indices into the map below.
 *
 * of_ip_mask_map: Array mapping index to mask
 * of_ip_mask_use_map: Boolean indication set when map is initialized
 * of_ip_mask_map_init: Initialize to default values; set "use map".
 */
#define OF_IP_MASK_MAP_COUNT 64
extern uint32_t of_ip_mask_map[OF_IP_MASK_MAP_COUNT];
extern int of_ip_mask_map_init_done;

#define OF_IP_MASK_INIT_CHECK \
    if (!of_ip_mask_map_init_done) of_ip_mask_map_init()

/**
 * Initialize map
 */
extern void of_ip_mask_map_init(void);

extern int of_ip_mask_map_set(int index, uint32_t mask);
extern int of_ip_mask_map_get(int index, uint32_t *mask);

/**
 * @brief Map from mask to index
 */

extern int of_ip_mask_to_index(uint32_t mask);

/**
 * @brief Map from index to mask
 */

extern uint32_t of_ip_index_to_mask(int index);

/**
 * The signalling of an untagged packet varies by OF version.
 * Use this macro to set the field value.
 */
#define OF_MATCH_UNTAGGED_VLAN_ID(version) \\
    ((version) == OF_VERSION_1_0 ? 0xffff : \\
     ((version) == OF_VERSION_1_1 ? 0xffff : 0))

/**
 * Version 1.1 had the notion of "any" vlan but must be set
 */
#define OF_MATCH_VLAN_TAG_PRESENT_ANY_ID(version) \\
    ((version) == OF_VERSION_1_0 ? 0 /* @fixme */  : \\
     ((version) == OF_VERSION_1_1 ? 0xfffe : 0x1000))
""")

def gen_oxm_defines(out):
    """
    Generate verbatim definitions for OXM
    """
    out.write("""

/* These are from the OpenFlow 1.2 header file */

/* OXM index values for bitmaps and parsing */
enum of_oxm_index_e {
    OF_OXM_INDEX_IN_PORT        = 0,  /* Switch input port. */
    OF_OXM_INDEX_IN_PHY_PORT    = 1,  /* Switch physical input port. */
    OF_OXM_INDEX_METADATA       = 2,  /* Metadata passed between tables. */
    OF_OXM_INDEX_ETH_DST        = 3,  /* Ethernet destination address. */
    OF_OXM_INDEX_ETH_SRC        = 4,  /* Ethernet source address. */
    OF_OXM_INDEX_ETH_TYPE       = 5,  /* Ethernet frame type. */
    OF_OXM_INDEX_VLAN_VID       = 6,  /* VLAN id. */
    OF_OXM_INDEX_VLAN_PCP       = 7,  /* VLAN priority. */
    OF_OXM_INDEX_IP_DSCP        = 8,  /* IP DSCP (6 bits in ToS field). */
    OF_OXM_INDEX_IP_ECN         = 9,  /* IP ECN (2 bits in ToS field). */
    OF_OXM_INDEX_IP_PROTO       = 10, /* IP protocol. */
    OF_OXM_INDEX_IPV4_SRC       = 11, /* IPv4 source address. */
    OF_OXM_INDEX_IPV4_DST       = 12, /* IPv4 destination address. */
    OF_OXM_INDEX_TCP_SRC        = 13, /* TCP source port. */
    OF_OXM_INDEX_TCP_DST        = 14, /* TCP destination port. */
    OF_OXM_INDEX_UDP_SRC        = 15, /* UDP source port. */
    OF_OXM_INDEX_UDP_DST        = 16, /* UDP destination port. */
    OF_OXM_INDEX_SCTP_SRC       = 17, /* SCTP source port. */
    OF_OXM_INDEX_SCTP_DST       = 18, /* SCTP destination port. */
    OF_OXM_INDEX_ICMPV4_TYPE    = 19, /* ICMP type. */
    OF_OXM_INDEX_ICMPV4_CODE    = 20, /* ICMP code. */
    OF_OXM_INDEX_ARP_OP         = 21, /* ARP opcode. */
    OF_OXM_INDEX_ARP_SPA        = 22, /* ARP source IPv4 address. */
    OF_OXM_INDEX_ARP_TPA        = 23, /* ARP target IPv4 address. */
    OF_OXM_INDEX_ARP_SHA        = 24, /* ARP source hardware address. */
    OF_OXM_INDEX_ARP_THA        = 25, /* ARP target hardware address. */
    OF_OXM_INDEX_IPV6_SRC       = 26, /* IPv6 source address. */
    OF_OXM_INDEX_IPV6_DST       = 27, /* IPv6 destination address. */
    OF_OXM_INDEX_IPV6_FLABEL    = 28, /* IPv6 Flow Label */
    OF_OXM_INDEX_ICMPV6_TYPE    = 29, /* ICMPv6 type. */
    OF_OXM_INDEX_ICMPV6_CODE    = 30, /* ICMPv6 code. */
    OF_OXM_INDEX_IPV6_ND_TARGET = 31, /* Target address for ND. */
    OF_OXM_INDEX_IPV6_ND_SLL    = 32, /* Source link-layer for ND. */
    OF_OXM_INDEX_IPV6_ND_TLL    = 33, /* Target link-layer for ND. */
    OF_OXM_INDEX_MPLS_LABEL     = 34, /* MPLS label. */
    OF_OXM_INDEX_MPLS_TC        = 35, /* MPLS TC. */
};

#define OF_OXM_BIT(index) (((uint64_t) 1) << (index))

/*
 * The generic match structure uses the OXM bit indices for it's
 * bitmasks for active and masked values
 */
""")
    for key, entry in match.of_match_members.items():
        out.write("""
/* Mask/value check/set macros for %(key)s */

/**
 * Set the mask for an exact match of %(key)s
 */
#define OF_MATCH_MASK_%(ku)s_EXACT_SET(_match)   \\
    MEMSET(&(_match)->masks.%(key)s, 0xff, \\
        sizeof(((_match)->masks).%(key)s))

/**
 * Clear the mask for %(key)s making that field inactive for the match
 */
#define OF_MATCH_MASK_%(ku)s_CLEAR(_match) \\
    MEMSET(&(_match)->masks.%(key)s, 0, \\
        sizeof(((_match)->masks).%(key)s))

/**
 * Test whether the match is exact for %(key)s
 */
#define OF_MATCH_MASK_%(ku)s_EXACT_TEST(_match) \\
    OF_VARIABLE_IS_ALL_ONES(&(((_match)->masks).%(key)s))

/**
 * Test whether key %(key)s is being checked in the match
 */
#define OF_MATCH_MASK_%(ku)s_ACTIVE_TEST(_match) \\
    OF_VARIABLE_IS_NON_ZERO(&(((_match)->masks).%(key)s))

""" % dict(key=key, bit=match.oxm_index(key), ku=key.upper()))

def gen_incompat_members(out=sys.stdout):
    """
    Generate a macro that lists all the unified fields which are
    incompatible with v1 matches
    """
    out.write("""
/* Identify bits in unified match that are incompatible with V1, V2 matches */
#define OF_MATCH_V1_INCOMPAT ( (uint64_t)0 """)
    for key in match.of_match_members:
        if key in match.of_v1_keys:
            continue
        out.write("\\\n    | ((uint64_t)1 << %s)" % match.oxm_index(key))
    out.write(")\n\n")

    out.write("#define OF_MATCH_V2_INCOMPAT ( (uint64_t)0 ")
    for key in match.of_match_members:
        if key in match.of_v2_keys:
            continue
        out.write("\\\n    | ((uint64_t)1 << %s)" % match.oxm_index(key))
    out.write(""")

/* Indexed by version number */
extern uint64_t of_match_incompat[4];
""")


# # FIXME:  Make these version specific
# def name_to_index(a, name, key="name"):
#     """
#     Given an array, a, with each entry a dict, and a name,
#     find the entry with key matching name and return the index
#     """
#     count = 0
#     for e in a:
#         if e[key] == name:
#             return count
#         count += 1
#     return -1

def gen_wc_convert_literal(out):
    """
    A bunch of literal C code that's associated with match conversions
    @param out The output file handle
    """
    out.write("""

/* Some internal macros and utility functions */

/* For counting bits in a uint32 */
#define _VAL_AND_5s(v)  ((v) & 0x55555555)
#define _VAL_EVERY_OTHER(v)  (_VAL_AND_5s(v) + _VAL_AND_5s(v >> 1))
#define _VAL_AND_3s(v)  ((v) & 0x33333333)
#define _VAL_PAIRS(v)  (_VAL_AND_3s(v) + _VAL_AND_3s(v >> 2))
#define _VAL_QUADS(v)  (((val) + ((val) >> 4)) & 0x0F0F0F0F)
#define _VAL_BYTES(v)  ((val) + ((val) >> 8))

/**
 * Counts the number of bits set in an integer
 */
static inline int
_COUNT_BITS(unsigned int val)
{
    val = _VAL_EVERY_OTHER(val);
    val = _VAL_PAIRS(val);
    val = _VAL_QUADS(val);
    val = _VAL_BYTES(val);

    return (val & 0XFF) + ((val >> 16) & 0xFF);
}

/* Indexed by version number */
uint64_t of_match_incompat[4] = {
    -1,
    OF_MATCH_V1_INCOMPAT,
    OF_MATCH_V2_INCOMPAT,
    0
};

""")


def gen_unified_match_to_v1(out):
    """
    Generate C code to convert a unified match structure to a V1 match struct
    @param out The output file handle
    """

    out.write("""
/**
 * Check if match is compatible with OF 1.0
 * @param match The match being checked
 */
static inline int
of_match_v1_compat_check(of_match_t *match)
{
""")
    for key in match.of_match_members:
        if key in match.of_v1_keys:
            continue
        out.write("""
    if (OF_MATCH_MASK_%(ku)s_ACTIVE_TEST(match)) {
        return 0;
    }
""" % dict(ku=key.upper()))

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

    out.write("""
/**
 * Convert a generic match object to an OF_VERSION_1_0 object
 * @param src Pointer to the generic match object source
 * @param dst Pointer to the OF 1.0 wire structure
 *
 * The wire structure is initialized by this function if it doesn't
 * not have the proper object ID.
 */

int
of_match_to_wire_match_v1(of_match_t *src, of_match_v1_t *dst)
{
    of_wc_bmap_t wildcards = 0;
    int ip_mask_index;

    if ((src == NULL) || (dst == NULL)) {
        return OF_ERROR_PARAM;
    }
    if (!of_match_v1_compat_check(src)) {
        return OF_ERROR_COMPAT;
    }
    if (dst->object_id != OF_MATCH_V1) {
        of_match_v1_init(dst, OF_VERSION_1_0, 0, 0);
    }
""")
    for key in sorted(match.of_v1_keys):
        if key in ["ipv4_src", "ipv4_dst"]: # Special cases for masks here
            out.write("""
    if (OF_MATCH_MASK_%(ku)s_ACTIVE_TEST(src)) {
        ip_mask_index = of_ip_mask_to_index(src->masks.%(key)s);
        of_match_v1_%(key)s_set(dst, src->fields.%(key)s);
    } else { /* Wildcarded, look for 0 mask */
        ip_mask_index = of_ip_mask_to_index(0);
    }
    OF_MATCH_V1_WC_%(ku)s_SET(wildcards, ip_mask_index);
""" % dict(key=key, ku=key.upper()))
        else:
            out.write("""
    if (OF_MATCH_MASK_%(ku)s_ACTIVE_TEST(src)) {
        of_match_v1_%(key)s_set(dst, src->fields.%(key)s);
    } else {
        OF_MATCH_V1_WC_%(ku)s_SET(wildcards);
    }
""" % dict(key=key, ku=key.upper()))

    out.write("""
    of_match_v1_wildcards_set(dst, wildcards);

    return OF_ERROR_NONE;
}
""")

def all_ones_mask(d_type):
    if d_type == "of_mac_addr_t":
        return "of_mac_addr_all_ones"
    else:
        return "((%s) -1)" % d_type

def gen_unified_match_to_v2(out):
    """
    Generate C code to convert a unified match structure to a V2 match struct
    @param out The output file handle
    """

    out.write("""
/**
 * Check if match is compatible with OF 1.0
 * @param match The match being checked
 */
static inline int
of_match_v2_compat_check(of_match_t *match)
{
""")
    for key in match.of_match_members:
        if key in match.of_v2_keys:
            continue
        out.write("""
    if (OF_MATCH_MASK_%(ku)s_ACTIVE_TEST(match)) {
        return 0;
    }
""" % dict(ku=key.upper()))

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

    out.write("""
/**
 * Convert a generic match object to an OF_VERSION_1_1 object
 * @param src Pointer to the generic match object source
 * @param dst Pointer to the OF 1.1 wire structure
 *
 * The wire structure is initialized by this function.
 */

int
of_match_to_wire_match_v2(of_match_t *src, of_match_v2_t *dst)
{
    of_wc_bmap_t wildcards = 0;

    if ((src == NULL) || (dst == NULL)) {
        return OF_ERROR_PARAM;
    }
    if (!of_match_v2_compat_check(src)) {
        return OF_ERROR_COMPAT;
    }
    if (dst->object_id != OF_MATCH_V2) {
        of_match_v2_init(dst, OF_VERSION_1_1, 0, 0);
    }
""")
    for key in match.of_v2_keys:
        if key in match.of_v2_full_mask:
            ones_mask = all_ones_mask(match.of_match_members[key]["m_type"])
            out.write("""
    if (OF_MATCH_MASK_%(ku)s_ACTIVE_TEST(src)) {
        if (!OF_MATCH_MASK_%(ku)s_EXACT_TEST(src)) {
            of_match_v2_%(key)s_mask_set(dst,
                src->masks.%(key)s);
        } else { /* Exact match; use all ones mask */
            of_match_v2_%(key)s_mask_set(dst,
                %(ones_mask)s);
        }
        of_match_v2_%(key)s_set(dst, src->fields.%(key)s);
    }

""" % dict(key=key, ku=key.upper(), ones_mask=ones_mask))
        else:
            out.write("""
    if (!OF_MATCH_MASK_%(ku)s_EXACT_TEST(src)) {
        return OF_ERROR_COMPAT;
    }
    if (OF_MATCH_MASK_%(ku)s_ACTIVE_TEST(src)) {
        of_match_v2_%(key)s_set(dst, src->fields.%(key)s);
    } else {
        OF_MATCH_V2_WC_%(ku)s_SET(wildcards);
    }
""" % dict(key=key, ku=key.upper(),
           wc_bit="OF_MATCH_WC_V2_%s" % key.upper()))

    out.write("""
    of_match_v2_wildcards_set(dst, wildcards);

    return OF_ERROR_NONE;
}
""")

def gen_unified_match_to_v3(out):
    """
    Generate C code to convert a unified match structure to a V3 match

    This is much easier as the unified struct is based on V3
    @param out The output file handle
    """
    out.write("""
static int
populate_oxm_list(of_match_t *src, of_list_oxm_t *oxm_list)
{
    of_oxm_t oxm_entry;

    /* For each active member, add an OXM entry to the list */
""")
    # @fixme Would like to generate the list in some reasonable order
    for key, entry in match.of_match_members.items():
        out.write("""\
    if (OF_MATCH_MASK_%(ku)s_ACTIVE_TEST(src)) {
        if (!OF_MATCH_MASK_%(ku)s_EXACT_TEST(src)) {
            of_oxm_%(key)s_masked_t *elt;
            elt = &oxm_entry.%(key)s_masked;

            of_oxm_%(key)s_masked_init(elt,
                src->version, -1, 1);
            of_list_oxm_append_bind(oxm_list, &oxm_entry);
            of_oxm_%(key)s_masked_value_set(elt, 
                   src->fields.%(key)s);
            of_oxm_%(key)s_masked_value_mask_set(elt, 
                   src->masks.%(key)s);
        } else {  /* Active, but not masked */
            of_oxm_%(key)s_t *elt;
            elt = &oxm_entry.%(key)s;
            of_oxm_%(key)s_init(elt,
                src->version, -1, 1);
            of_list_oxm_append_bind(oxm_list, &oxm_entry);
            of_oxm_%(key)s_value_set(elt, src->fields.%(key)s);
        }
    }
""" % dict(key=key, ku=key.upper()))
    out.write("""
    return OF_ERROR_NONE;
}

/**
 * Convert a generic match object to an OF_VERSION_1_2 object
 * @param src Pointer to the generic match object source
 * @param dst Pointer to the OF 1.2 wire structure
 *
 * The wire structure is initialized by this function if the object
 * id is not correct in the object
 */

int
of_match_to_wire_match_v3(of_match_t *src, of_match_v3_t *dst)
{
    int rv = OF_ERROR_NONE;
    of_list_oxm_t *oxm_list;

    if ((src == NULL) || (dst == NULL)) {
        return OF_ERROR_PARAM;
    }
    if (dst->object_id != OF_MATCH_V3) {
        of_match_v3_init(dst, src->version, 0, 0);
    }
    if ((oxm_list = of_list_oxm_new(src->version)) == NULL) {
        return OF_ERROR_RESOURCE;
    }

    rv = populate_oxm_list(src, oxm_list);

    if (rv == OF_ERROR_NONE) {
        rv = of_match_v3_oxm_list_set(dst, oxm_list);
    }

    of_list_oxm_delete(oxm_list);

    return rv;
}
""")

def gen_v1_to_unified_match(out):
    """
    Generate the code that maps a v1 wire format match object
    to a unified match object
    """
    # for each v1 member, if not in wildcards
    # translate to unified.  Treat nw_src/dst specially
    out.write("""

/**
 * Convert an OF_VERSION_1_0 object to a generic match object
 * @param src Pointer to the OF 1.0 wire structure source
 * @param dst Pointer to the generic match object destination
 *
 * The wire structure is initialized by this function.
 */

int
of_match_v1_to_match(of_match_v1_t *src, of_match_t *dst)
{
    of_wc_bmap_t wc;
    int count;

    MEMSET(dst, 0, sizeof(*dst));
    dst->version = src->version;

    of_match_v1_wildcards_get(src, &wc);
""")
    # Deal with nw fields first
    out.write("""
    /* Handle L3 src and dst wildcarding first */
    /* @fixme Check mask values are properly treated for ipv4 src/dst */
    if ((count = OF_MATCH_V1_WC_IPV4_DST_GET(wc)) < 32) {
        of_match_v1_ipv4_dst_get(src, &dst->fields.ipv4_dst);
        if (count > 0) { /* Not exact match */
            dst->masks.ipv4_dst = ~(((uint32_t)1 << count) - 1);
        } else {
            OF_MATCH_MASK_IPV4_DST_EXACT_SET(dst);
        }
    }
""")
    for key in sorted(match.of_v1_keys):
        if key in ["ipv4_src", "ipv4_dst"]: # Special cases for masks here
            out.write("""
    count = OF_MATCH_V1_WC_%(ku)s_GET(wc);
    dst->masks.%(key)s = of_ip_index_to_mask(count);
    /* @todo Review if we should only get the addr when masks.%(key)s != 0 */
    of_match_v1_%(key)s_get(src, &dst->fields.%(key)s);
""" % dict(ku=key.upper(), key=key))
        else:
            out.write("""
    if (!(OF_MATCH_V1_WC_%(ku)s_TEST(wc))) {
        of_match_v1_%(key)s_get(src, &dst->fields.%(key)s);
        OF_MATCH_MASK_%(ku)s_EXACT_SET(dst);
    }
""" % dict(ku=key.upper(), key=key))

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

def gen_v2_to_unified_match(out):
    """
    Generate the code that maps a v2 wire format match object
    to a unified match object
    """
    out.write("""
int
of_match_v2_to_match(of_match_v2_t *src, of_match_t *dst)
{
    of_wc_bmap_t wc;

    MEMSET(dst, 0, sizeof(*dst));
    dst->version = src->version;

    of_match_v2_wildcards_get(src, &wc);
""")
    for key in match.of_v2_keys:
        if key in match.of_v2_full_mask:
            out.write("""
    of_match_v2_%(key)s_mask_get(src, &dst->masks.%(key)s);
    if (OF_VARIABLE_IS_NON_ZERO(&dst->masks.%(key)s)) { /* Matching something */
        of_match_v2_%(key)s_get(src, &dst->fields.%(key)s);
    }
""" % dict(ku=key.upper(), key=key))
        else:
            out.write("""
    if (!(OF_MATCH_V2_WC_%(ku)s_TEST(wc))) {
        of_match_v2_%(key)s_get(src, &dst->fields.%(key)s);
        OF_MATCH_MASK_%(ku)s_EXACT_SET(dst);
    }
""" % dict(ku=key.upper(), key=key))

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


def gen_v3_to_unified_match(out):
    """
    Generate the code that maps a v3 wire format match object
    to a unified match object
    """
    # Iterate thru the OXM list members
    out.write("""
int
of_match_v3_to_match(of_match_v3_t *src, of_match_t *dst)
{
    int rv;
    of_list_oxm_t oxm_list;
    of_oxm_t oxm_entry;
""")
#    for key in match.of_match_members:
#        out.write("    of_oxm_%s_t *%s;\n" % (key, key))
#        out.write("    of_oxm_%s_masked_t *%s_masked;\n" % (key, key))

    out.write("""
    MEMSET(dst, 0, sizeof(*dst));
    dst->version = src->version;

    of_match_v3_oxm_list_bind(src, &oxm_list);
    rv = of_list_oxm_first(&oxm_list, &oxm_entry);

    while (rv == OF_ERROR_NONE) {
        switch (oxm_entry.header.object_id) { /* What kind of entry is this */
""")
    for key in match.of_match_members:
        out.write("""
        case OF_OXM_%(ku)s_MASKED:
            of_oxm_%(key)s_masked_value_mask_get(
                &oxm_entry.%(key)s_masked,
                &dst->masks.%(key)s);
            of_oxm_%(key)s_masked_value_get(
                &oxm_entry.%(key)s,
                &dst->fields.%(key)s);
            break;
        case OF_OXM_%(ku)s:
            OF_MATCH_MASK_%(ku)s_EXACT_SET(dst);
            of_oxm_%(key)s_value_get(
                &oxm_entry.%(key)s,
                &dst->fields.%(key)s);
            break;
""" % (dict(ku=key.upper(), key=key)))

    out.write("""
        default:
             /* @fixme Add debug statement */
             return OF_ERROR_PARSE;
        } /* end switch */
        rv = of_list_oxm_next(&oxm_list, &oxm_entry);
    } /* end OXM iteration */

    return OF_ERROR_NONE;
}
""")

def gen_serialize(out):
    out.write("""
/**
 * Serialize a match structure according to the version passed
 * @param version The version to use for serialization protocol
 * @param match Pointer to the structure to serialize
 * @param octets Pointer to an octets object to fill out
 *
 * A buffer is allocated using normal internal ALLOC/FREE semantics
 * and pointed to by the octets object.  The length of the resulting
 * serialization is in octets->bytes.
 *
 * For 1.2 matches, returns the padded serialized structure
 *
 * Note that FREE must be called on octets->data when processing of
 * the object is complete.
 */

int
of_match_serialize(of_version_t version, of_match_t *match, of_octets_t *octets)
{
    int rv;

    switch (version) {
""")
    for version in of_g.of_version_range:
        out.write("""
    case %(ver_name)s:
        {
            of_match_v%(version)s_t *wire_match;
            wire_match = of_match_v%(version)s_new(version);
            if (wire_match == NULL) {
                return OF_ERROR_RESOURCE;
            }
            if ((rv = of_match_to_wire_match_v%(version)s(match, wire_match)) < 0) {
                of_match_v%(version)s_delete(wire_match);
                return rv;
            }
            octets->bytes = OF_MATCH_BYTES(wire_match->length);
            of_object_wire_buffer_steal((of_object_t *)wire_match,
                                        &octets->data);
            of_match_v%(version)s_delete(wire_match);
        }
        break;
""" % dict(version=version, ver_name=of_g.of_version_wire2name[version]))
    out.write("""
    default:
        return OF_ERROR_COMPAT;
    }

    return OF_ERROR_NONE;
}
""")


def gen_deserialize(out):
    out.write("""
/**
 * Deserialize a match structure according to the version passed
 * @param version The version to use for deserialization protocol
 * @param match Pointer to the structure to fill out
 * @param octets Pointer to an octets object holding serial buffer
 *
 * Normally the octets object will point to a part of a wire buffer.
 */

int
of_match_deserialize(of_version_t version, of_match_t *match,
                     of_octets_t *octets)
{
    if (octets->bytes == 0) { /* No match specified means all wildcards */
        MEMSET(match, 0, sizeof(*match));
        match->version = version;

        return OF_ERROR_NONE;
    }

    switch (version) {
""")
    for version in of_g.of_version_range:
        out.write("""
    case %(ver_name)s:
        { /* FIXME: check init bytes */
            uint8_t *tmp;
            of_match_v%(version)d_t wire_match;
            of_match_v%(version)d_init(&wire_match,
                   %(ver_name)s, -1, 1);
            of_object_buffer_bind((of_object_t *)&wire_match, 
                octets->data, octets->bytes, NULL);
            OF_TRY(of_match_v%(version)d_to_match(&wire_match, match));

            /* Free the wire buffer control block without freeing
             * octets->bytes. */
            of_wire_buffer_steal(wire_match.wire_object.wbuf, &tmp);
        }
        break;
""" % dict(version=version, ver_name=of_g.of_version_wire2name[version]))

    out.write("""
    default:
        return OF_ERROR_COMPAT;
    }

    return OF_ERROR_NONE;
}
""")

def gen_match_comp(out=sys.stdout):
    """
    Generate match comparison functions
    """
    out.write("""
/**
 * Determine "more specific" relationship between mac addrs
 * @return true if v1 is equal to or more specific than v2
 *
 * @todo Could be optimized
 *
 * Check: Every bit in v2 is set in v1; v1 may have add'l bits set.
 * That is, return false if there is a bit set in v2 and not in v1.
 */

static inline int
of_more_specific_ipv6(of_ipv6_t *v1, of_ipv6_t *v2) {
    int idx;

    for (idx = 0; idx < OF_IPV6_BYTES; idx++) {
        /* If there's a bit set in v2 that is clear in v1, return false */
        if (~v1->addr[idx] & v2->addr[idx]) {
            return 0;
        }
    }

    return 1;
}

/**
 * Boolean test if two values agree when restricted to a mask
 */

static inline int
of_restricted_match_ipv6(of_ipv6_t *v1, of_ipv6_t *v2, of_ipv6_t *mask) {
    int idx;

    for (idx = 0; idx < OF_IPV6_BYTES; idx++) {
        if ((v1->addr[idx] & mask->addr[idx]) != 
               (v2->addr[idx] & mask->addr[idx])) {
            return 0;
        }
    }

    return 1;
}

/**
 * Boolean test if two values "overlap" (agree on common masks)
 */

static inline int
of_overlap_ipv6(of_ipv6_t *v1, of_ipv6_t *v2,
                         of_ipv6_t *m1, of_ipv6_t *m2) {
    int idx;

    for (idx = 0; idx < OF_IPV6_BYTES; idx++) {
        if (((v1->addr[idx] & m1->addr[idx]) & m2->addr[idx]) != 
               ((v2->addr[idx] & m1->addr[idx]) & m2->addr[idx])) {
            return 0;
        }
    }

    return 1;
}

#define OF_MORE_SPECIFIC_IPV6(v1, v2) of_more_specific_ipv6((v1), (v2))

#define OF_RESTRICTED_MATCH_IPV6(v1, v2, mask) \\
    of_restricted_match_ipv6((v1), (v2), (mask))

#define OF_OVERLAP_IPV6(v1, v2, m1, m2) of_overlap_ipv6((v1), (v2), (m1), (m2))

/**
 * Determine "more specific" relationship between mac addrs
 * @return true if v1 is equal to or more specific than v2
 *
 * @todo Could be optimized
 *
 * Check: Every bit in v2 is set in v1; v1 may have add'l bits set.
 * That is, return false if there is a bit set in v2 and not in v1.
 */
static inline int
of_more_specific_mac_addr(of_mac_addr_t *v1, of_mac_addr_t *v2) {
    int idx;

    for (idx = 0; idx < OF_MAC_ADDR_BYTES; idx++) {
        /* If there's a bit set in v2 that is clear in v1, return false */
        if (~v1->addr[idx] & v2->addr[idx]) {
            return 0;
        }
    }

    return 1;
}

/**
 * Boolean test if two values agree when restricted to a mask
 */
static inline int
of_restricted_match_mac_addr(of_mac_addr_t *v1, of_mac_addr_t *v2, 
                             of_mac_addr_t *mask) {
    int idx;

    for (idx = 0; idx < OF_MAC_ADDR_BYTES; idx++) {
        if ((v1->addr[idx] & mask->addr[idx]) != 
               (v2->addr[idx] & mask->addr[idx])) {
            return 0;
        }
    }

    return 1;
}

/**
 * Boolean test if two values "overlap" (agree on common masks)
 */

static inline int
of_overlap_mac_addr(of_mac_addr_t *v1, of_mac_addr_t *v2,
                         of_mac_addr_t *m1, of_mac_addr_t *m2) {
    int idx;

    for (idx = 0; idx < OF_MAC_ADDR_BYTES; idx++) {
        if (((v1->addr[idx] & m1->addr[idx]) & m2->addr[idx]) != 
               ((v2->addr[idx] & m1->addr[idx]) & m2->addr[idx])) {
            return 0;
        }
    }

    return 1;
}

#define OF_MORE_SPECIFIC_MAC_ADDR(v1, v2) of_more_specific_mac_addr((v1), (v2))

#define OF_RESTRICTED_MATCH_MAC_ADDR(v1, v2, mask) \\
    of_restricted_match_mac_addr((v1), (v2), (mask))

#define OF_OVERLAP_MAC_ADDR(v1, v2, m1, m2) \\
    of_overlap_mac_addr((v1), (v2), (m1), (m2))

/**
 * More-specific-than macro for integer types; see above
 * @return true if v1 is equal to or more specific than v2
 *
 * If there is a bit that is set in v2 and not in v1, return false.
 */
#define OF_MORE_SPECIFIC_INT(v1, v2) (!(~(v1) & (v2)))

/**
 * Boolean test if two values agree when restricted to a mask
 */
#define OF_RESTRICTED_MATCH_INT(v1, v2, mask) \\
   (((v1) & (mask)) == ((v2) & (mask)))


#define OF_OVERLAP_INT(v1, v2, m1, m2) \\
    ((((v1) & (m1)) & (m2)) == (((v2) & (m1)) & (m2)))
""")

    out.write("""
/**
 * Compare two match structures for exact equality
 *
 * We just do memcmp assuming structs were memset to 0 on init
 */
static inline int
of_match_eq(of_match_t *match1, of_match_t *match2)
{
    return (MEMCMP(match1, match2, sizeof(of_match_t)) == 0);
}

/**
 * Is the entry match more specific than (or equal to) the query match?
 * @param entry Match expected to be more specific (subset of query)
 * @param query Match expected to be less specific (superset of entry)
 * @returns Boolean, see below
 *
 * The assumption is that a query is being done for a non-strict
 * match against an entry in a table.  The result is true if the
 * entry match indicates a more specific (but compatible) flow space
 * specification than that in the query match.  This means that the
 * values agree between the two where they overlap, and that each mask
 * for the entry is more specific than that of the query.
 *
 * The query has the less specific mask (fewer mask bits) so it is
 * used for the mask when checking values.
 */

static inline int
of_match_more_specific(of_match_t *entry, of_match_t *query)
{
    of_match_fields_t *q_m, *e_m;  /* Short hand for masks, fields */
    of_match_fields_t *q_f, *e_f;

    q_m = &query->masks;
    e_m = &entry->masks;
    q_f = &query->fields;
    e_f = &entry->fields;
""")
    for key, entry in match.of_match_members.items():
        q_m = "&q_m->%s" % key
        e_m = "&e_m->%s" % key
        q_f = "&q_f->%s" % key
        e_f = "&e_f->%s" % key
        if entry["m_type"] == "of_ipv6_t":
            comp = "OF_MORE_SPECIFIC_IPV6"
            match_type = "OF_RESTRICTED_MATCH_IPV6"
        elif entry["m_type"] == "of_mac_addr_t":
            comp = "OF_MORE_SPECIFIC_MAC_ADDR"
            match_type = "OF_RESTRICTED_MATCH_MAC_ADDR"
        else: # Integer
            comp = "OF_MORE_SPECIFIC_INT"
            match_type = "OF_RESTRICTED_MATCH_INT"
            q_m = "q_m->%s" % key
            e_m = "e_m->%s" % key
            q_f = "q_f->%s" % key
            e_f = "e_f->%s" % key
        out.write("""
    /* Mask and values for %(key)s */
    if (!%(comp)s(%(e_m)s, %(q_m)s)) {
        return 0;
    }
    if (!%(match_type)s(%(e_f)s, %(q_f)s,
            %(q_m)s)) {
        return 0;
    }
""" % dict(match_type=match_type, comp=comp, q_f=q_f, e_f=e_f, 
           q_m=q_m, e_m=e_m, key=key))

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

    out.write("""

/**
 * Do two entries overlap?
 * @param match1 One match struct
 * @param match2 Another match struct
 * @returns Boolean: true if there is a packet that would match both
 *
 */

static inline int
of_match_overlap(of_match_t *match1, of_match_t *match2)
{
    of_match_fields_t *m1, *m2;  /* Short hand for masks, fields */
    of_match_fields_t *f1, *f2;

    m1 = &match1->masks;
    m2 = &match2->masks;
    f1 = &match1->fields;
    f2 = &match2->fields;
""")
    for key, entry in match.of_match_members.items():
        m1 = "&m1->%s" % key
        m2 = "&m2->%s" % key
        f1 = "&f1->%s" % key
        f2 = "&f2->%s" % key
        if entry["m_type"] == "of_ipv6_t":
            check = "OF_OVERLAP_IPV6"
        elif entry["m_type"] == "of_mac_addr_t":
            check = "OF_OVERLAP_MAC_ADDR"
        else: # Integer
            check = "OF_OVERLAP_INT"
            m1 = "m1->%s" % key
            m2 = "m2->%s" % key
            f1 = "f1->%s" % key
            f2 = "f2->%s" % key
        out.write("""
    /* Check overlap for %(key)s */
    if (!%(check)s(%(f1)s, %(f2)s, 
        %(m2)s, %(m1)s)) {
        return 0; /* This field differentiates; all done */
    }
""" % dict(check=check, f1=f1, f2=f2, m1=m1, m2=m2, key=key))

    out.write("""
    return 1; /* No field differentiates matches */
}
""")

def gen_match_conversions(out=sys.stdout):
    match.match_sanity_check()
    gen_wc_convert_literal(out)
    out.write("""
/**
 * IP Mask map.  IP maks wildcards from OF 1.0 are interpretted as
 * indices into the map below.
 */

int of_ip_mask_map_init_done = 0;
uint32_t of_ip_mask_map[OF_IP_MASK_MAP_COUNT];
void
of_ip_mask_map_init(void)
{
    int idx;

    MEMSET(of_ip_mask_map, 0, sizeof(of_ip_mask_map));
    for (idx = 0; idx < 32; idx++) {
        of_ip_mask_map[idx] = ~((1U << idx) - 1);
    }

    of_ip_mask_map_init_done = 1;
}

/**
 * @brief Set non-default IP mask for given index
 */
int
of_ip_mask_map_set(int index, uint32_t mask)
{
    OF_IP_MASK_INIT_CHECK;

    if ((index < 0) || (index >= OF_IP_MASK_MAP_COUNT)) {
        return OF_ERROR_RANGE;
    }
    of_ip_mask_map[index] = mask;

    return OF_ERROR_NONE;
}

/**
 * @brief Get a non-default IP mask for given index
 */
int
of_ip_mask_map_get(int index, uint32_t *mask)
{
    OF_IP_MASK_INIT_CHECK;

    if ((mask == NULL) || (index < 0) || (index >= OF_IP_MASK_MAP_COUNT)) {
        return OF_ERROR_RANGE;
    }
    *mask = of_ip_mask_map[index];

    return OF_ERROR_NONE;
}

/**
 * @brief Return the index (used as the WC field in 1.0 match) given the mask
 */

int
of_ip_mask_to_index(uint32_t mask)
{
    int idx;

    OF_IP_MASK_INIT_CHECK;

    /* Handle most common cases directly */
    if ((mask == 0) && (of_ip_mask_map[63] == 0)) {
        return 63;
    }
    if ((mask == 0xffffffff) && (of_ip_mask_map[0] == 0xffffffff)) {
        return 0;
    }

    for (idx = 0; idx < OF_IP_MASK_MAP_COUNT; idx++) {
        if (mask == of_ip_mask_map[idx]) {
            return idx;
        }
    }

    LOCI_LOG_INFO("OF 1.0: Could not map IP addr mask 0x%x", mask);
    return 0x3f;
}

/**
 * @brief Return the mask for the given index
 */

uint32_t
of_ip_index_to_mask(int index)
{
    OF_IP_MASK_INIT_CHECK;

    if (index >= OF_IP_MASK_MAP_COUNT) {
        LOCI_LOG_INFO("IP index to map: bad index %d", index);
        return 0;
    }

    return of_ip_mask_map[index];
}

""")

    gen_unified_match_to_v1(out)
    gen_unified_match_to_v2(out)
    gen_unified_match_to_v3(out)
    gen_v1_to_unified_match(out)
    gen_v2_to_unified_match(out)
    gen_v3_to_unified_match(out)
    return
