# 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.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. */
    OF_OXM_INDEX_SRC_META_ID = 36,
    OF_OXM_INDEX_DST_META_ID = 37,
};

#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 const 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 */
const 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
