# 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.

#
# Miscellaneous type information
#
# Define the map between sub-class types and wire values.  In each
# case, an array indexed by wire version gives a hash from identifier
# to wire value.
#

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

invalid_type = "invalid_type"

################################################################
#
# Define type data for inheritance classes:
#   instructions, actions, queue properties and OXM
#
# Messages are not in this group; they're treated specially for now
#
# These are indexed by wire protocol number
#
################################################################

instruction_types = {
    of_g.VERSION_1_0:dict(),
    of_g.VERSION_1_1:dict(),
    of_g.VERSION_1_2:dict(),
    of_g.VERSION_1_3:dict()
    }

instruction_id_types = {
    of_g.VERSION_1_0:dict(),
    of_g.VERSION_1_1:dict(),
    of_g.VERSION_1_2:dict(),
    of_g.VERSION_1_3:dict()
    }

action_types = {
    of_g.VERSION_1_0:dict(),
    of_g.VERSION_1_1:dict(),
    of_g.VERSION_1_2:dict(),
    of_g.VERSION_1_3:dict(),
    }

action_id_types = {
    of_g.VERSION_1_0:dict(),
    of_g.VERSION_1_1:dict(),
    of_g.VERSION_1_2:dict(),
    of_g.VERSION_1_3:dict(),
    }

queue_prop_types = {
    of_g.VERSION_1_0:dict(),
    of_g.VERSION_1_1:dict(),
    of_g.VERSION_1_2:dict(),
    of_g.VERSION_1_3:dict()
    }

bsn_vport_types = {
    of_g.VERSION_1_0:dict(),
    of_g.VERSION_1_1:dict(),
    of_g.VERSION_1_2:dict(),
    of_g.VERSION_1_3:dict(),
    }

oxm_types = {
    of_g.VERSION_1_0:dict(),
    of_g.VERSION_1_1:dict(),
    of_g.VERSION_1_2:dict(),
    of_g.VERSION_1_3:dict(),
    }

hello_elem_types = {
    of_g.VERSION_1_0:dict(),
    of_g.VERSION_1_1:dict(),
    of_g.VERSION_1_2:dict(),
    of_g.VERSION_1_3:dict(),
    }

table_feature_prop_types = {
    of_g.VERSION_1_0:dict(),
    of_g.VERSION_1_1:dict(),
    of_g.VERSION_1_2:dict(),
    of_g.VERSION_1_3:dict(),
    }

meter_band_types = {
    of_g.VERSION_1_0:dict(),
    of_g.VERSION_1_1:dict(),
    of_g.VERSION_1_2:dict(),
    of_g.VERSION_1_3:dict(),
    }

bsn_tlv_types = {
    of_g.VERSION_1_0:dict(),
    of_g.VERSION_1_1:dict(),
    of_g.VERSION_1_2:dict(),
    of_g.VERSION_1_3:dict(),
    }

# All inheritance data for non-messages
inheritance_data = dict(
    of_instruction = instruction_types,
    of_instruction_id = instruction_id_types,
    of_action = action_types,
    of_action_id = action_id_types,
    of_oxm = oxm_types,
    of_queue_prop = queue_prop_types,
    of_hello_elem = hello_elem_types,
    of_table_feature_prop = table_feature_prop_types,
    of_meter_band = meter_band_types,
    # BSN specific inheritance extensions
    of_bsn_vport = bsn_vport_types,
    of_bsn_tlv = bsn_tlv_types,
    )

def class_is_virtual(cls):
    """
    Returns True if cls is a virtual class
    """
    if cls.endswith("header"):
        return True
    if loxi_utils.class_is_list(cls):
        return True
    return loxi_globals.unified.class_by_name(cls).virtual

################################################################
#
# type_val is the primary data structure that maps an
# (class_name, version) pair to the wire data type value
#
################################################################

type_val = dict()
inheritance_map = dict()

def generate_maps():
    for parent, versioned in inheritance_data.items():
        inheritance_map[parent] = set()
        for ver, subclasses in versioned.items():
            for subcls in subclasses:
                inheritance_map[parent].add(subcls)

    for parent, versioned in inheritance_data.items():
        for version, subclasses in versioned.items():
            for subcls, value in subclasses.items():
                name = parent + "_" + subcls
                type_val[(name, version)] = value

    # Special case OF-1.2 match type
    type_val[("of_match_v3", of_g.VERSION_1_2)] = 1
    type_val[("of_match_v3", of_g.VERSION_1_3)] = 1

def sub_class_map(base_type, version):
    """
    Returns an iterable object giving the instance nameys and subclass types
    for the base_type, version values
    """
    rv = []
    if base_type not in inheritance_map:
        return rv

    for instance in inheritance_map[base_type]:
        subcls = loxi_utils.instance_to_class(instance, base_type)
        if not loxi_utils.class_in_version(subcls, version):
            continue
        rv.append((instance, subcls))

    return rv
