# 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 Match data representation
#
# @fixme This still has lots of C specific code that should be moved into c_gen

import sys
import c_gen.of_g_legacy as of_g
from generic_utils import *
import c_gen.loxi_utils_legacy as loxi_utils
import loxi_globals

#
# Use 1.2 match semantics for common case
#
# Generate maps between generic match and version specific matches
# Generate dump functions for generic match
# Generate dump functions for version specific matches

## @var of_match_members
# The dictionary from unified match members to type and indexing info
#
# Keys:
#   name The unified name used for the member
#   m_type The data type used for the object in unified structure
#   order Used to define an order for readability
#   v1_wc_shift The WC shift in OF 1.0
#   v2_wc_shift The WC shift in OF 1.1
#
# We use the 1.2 names and alias older names

of_match_members = dict()

of_v1_keys = [
    "eth_dst",
    "eth_src",
    "eth_type",
    "in_port",
    "ipv4_dst",
    "ip_proto",
    "ipv4_src",
    "ip_dscp",
    "tcp_dst",  # Means UDP too for 1.0 and 1.1
    "tcp_src",  # Means UDP too for 1.0 and 1.1
    "vlan_pcp",
    "vlan_vid"
    ]

v1_wc_shifts = dict(
    in_port=0,
    vlan_vid=1,
    eth_src=2,
    eth_dst=3,
    eth_type=4,
    ip_proto=5,
    tcp_src=6,
    tcp_dst=7,
    ipv4_src=8,
    ipv4_dst=14,
    vlan_pcp=20,
    ip_dscp=21,
)

of_v2_keys = [
    "eth_dst",
    "eth_src",
    "eth_type",
    "in_port",
    "ipv4_dst",
    "ip_proto",
    "ipv4_src",
    "ip_dscp",
    "tcp_dst",  # Means UDP too for 1.0 and 1.1
    "tcp_src",  # Means UDP too for 1.0 and 1.1
    "vlan_pcp",
    "vlan_vid",
    "mpls_label",
    "mpls_tc",
    "metadata"
    ]

of_v2_full_mask = [
    "eth_dst",
    "eth_src",
    "ipv4_dst",
    "ipv4_src",
    "metadata"
    ]

v2_wc_shifts = dict(
    in_port=0,
    vlan_vid=1,
    vlan_pcp=2,
    eth_type=3,
    ip_dscp=4,
    ip_proto=5,
    tcp_src=6,
    tcp_dst=7,
    mpls_label=8,
    mpls_tc=9,
)

# Map from wire version to list of match keys for that version
match_keys = {
    1: of_v1_keys,
    2: of_v2_keys,
    3: [],
    4: [],
}

# Complete list of match keys, sorted by the standard order
match_keys_sorted = []

# Generate the of_match_members, match_keys, and match_keys_sorted
# datastructures from the IR and the v1/v2 tables above
def build():
    for uclass in loxi_globals.unified.classes:
        if not uclass.is_oxm or uclass.name == 'of_oxm':
            continue
        if uclass.name.endswith('_masked'):
            continue

        name = uclass.name[7:] # of_oxm_*
        value_member = uclass.member_by_name('value')
        type_len = uclass.member_by_name('type_len').value

        # Order match keys by their type_len
        if (type_len & 0xffff0000) == 0x80000000:
            # OpenFlow Basic comes first
            order = type_len & 0x0000ffff
        else:
            order = type_len

        match_member = dict(
            name=name,
            m_type=value_member.oftype,
            order=order)
        if name in v1_wc_shifts:
            match_member['v1_wc_shift'] = v1_wc_shifts[name]
        if name in v2_wc_shifts:
            match_member['v2_wc_shift'] = v2_wc_shifts[name]

        of_match_members[name] = match_member

        for version in uclass.version_classes:
            assert name not in match_keys[version.wire_version]
            match_keys[version.wire_version].append(name)

    match_keys_sorted.extend(
        sorted(of_match_members.keys(),
               key=lambda entry:of_match_members[entry]["order"]))

##
# Check that all members in the hash are recognized as match keys
def match_sanity_check():
    count = 0
    for match_v in ["of_match_v1", "of_match_v2"]:
        count += 1
        for mm in of_g.unified[match_v][count]["members"]:
            key = mm["name"]
            if key.find("_mask") >= 0:
                continue
            if loxi_utils.skip_member_name(key):
                continue
            if key == "wildcards":
                continue
            if not key in of_match_members:
                print "Key %s not found in match struct, v %s" % (key, match_v)
                sys.exit(1)

    # Generate list of OXM names from the unified classes
    oxm_names = [x[7:] for x in of_g.unified.keys() if
                 x.startswith('of_oxm_') and
                 x.find('masked') < 0 and
                 x.find('header') < 0]

    # Check that all OXMs are in the match members
    for key in oxm_names:
        if not key in of_match_members:
            if not (key.find("_masked") > 0):
                debug("Key %s in OXM, not of_match_members" % key)
                sys.exit(1)
            if not key[:-7] in of_match_members:
                debug("Key %s in OXM, but %s not in of_match_members"
                      % (key, key[:-7]))
                sys.exit(1)

    # Check that all match members are in the OXMs
    for key in of_match_members:
        if not key in oxm_names:
            debug("Key %s in of_match_members, not in OXM" % key)
            sys.exit(1)
        oxm_type = of_g.unified['of_oxm_%s' % key]['union']['value']['m_type']
        if of_match_members[key]["m_type"] != oxm_type:
            debug("Type mismatch for key %s in oxm data: %s vs %s" %
                  (key, of_match_members[key]["m_type"], oxm_type))
            sys.exit(1)
