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

# Prototype of an Intermediate Object model for the java code generator
# A lot of this stuff could/should probably be merged with the python utilities

import collections
from collections import namedtuple, defaultdict, OrderedDict
import logging
import os
import pdb
import re

from generic_utils import find, memoize, OrderedSet, OrderedDefaultDict
import of_g
from loxi_ir import *
import loxi_front_end.type_maps as type_maps
import loxi_utils.loxi_utils as loxi_utils
import py_gen.util as py_utils
import test_data

import java_gen.java_type as java_type
from java_gen.java_type import erase_type_annotation

# Key is modified name of error code; value is OFErrorType value string
error_type_map = {}

def adjust_ir():
    """
    For Java we change of_error_message to combine the 16-bit type and code
    fields into a single 32-bit code field and we combine the per-error-type
    code enums into a single ofp_error_code enum. This enables the generated
    OFErrorMsg class to have a getCode method that can return all supported
    error codes. Otherwise we'd need to do something like having per-error-type
    subclasses of OFErrorMsg that had a getCode that returned the different
    error codes for each error type, which would be less convenient for clients
    and would also entail changing the LOXI OF input files and impacting other
    language backends.
    """
    for version in of_g.target_version_list:
        of_protocol = of_g.ir[version]
        error_type = find(lambda e: e.name == "ofp_error_type", of_protocol.enums)
        if error_type == None:
            raise Exception("ofp_error_type enum not found; OF version: " + str(version))
        error_code_entries = []
        # For each error type value look up the corresponding error code enum.
        # Add those values to the combined entries for the new ofp_error_code
        # enum. The name of the new value is formed by concatenating the name
        # of the error type value with the name of the old error code value.
        for error_type_entry in error_type.entries:
            # Strip off the OFPxx prefix
            prefix_length = error_type_entry.name.find('_')
            if prefix_length < 0:
                raise Exception("OFPET prefix not found for ofp_error_type value " + error_type_entry.name + "; OF version: " + str(version))
            error_type_entry_name = error_type_entry.name[prefix_length+1:]
            if error_type_entry_name == "EXPERIMENTER":
                # There isn't an error code enum defined for the experimenter error type
                # FIXME: Need to add support for the message ofp_error_experimenter_msg format
                continue
            # The per-error-type code enums follow a naming conventions where
            # the middle part of the enum name is the same as the name of the
            # error type value (except lower-case).
            error_code_enum_name = "ofp_" + error_type_entry_name.lower() + "_code"
            # Look up the error code enum from the IR
            error_code_enum = None
            for i, enum in enumerate(of_protocol.enums):
                if enum.name == error_code_enum_name:
                    error_code_enum = enum
                    # We don't want to generate code for the per-error-type
                    # enum so remove it from the IR
                    del of_protocol.enums[i]
                    break
            if error_code_enum == None:
                raise Exception("Error code enum not found: " + error_code_enum_name + "; OF version: " + str(version))
            for error_code_entry in error_code_enum.entries:
                # Strip off the prefix from the entry name
                prefix_length = error_code_entry.name.find('_')
                if prefix_length < 0:
                    raise Exception("Prefix not found for error code value " + error_code_entry.name + "; OF version: " + str(version))
                error_code_entry_name = error_code_entry.name[prefix_length+1:]
                # Combine the entry type name and the error code name
                error_code_entry_name = error_type_entry_name + "_" + error_code_entry_name
                # Combine the entry type value and the error code value
                error_code_entry_value = (error_type_entry.value << 16) + error_code_entry.value
                # Add the enum entry to the combined ofp_error_code
                # Note that the "OFPEC" prefix is arbitrary. It will be stripped
                # off again during Java code generation, but there needs to be
                # some/any prefix
                error_code_entries.append(OFEnumEntry("OFPEC_" + error_code_entry_name, error_code_entry_value, {}))
                error_type_map[error_code_entry_name] = error_type_entry_name
        # We've collected all of the entries. Now we can add the enum to the IR
        of_protocol.enums.append(OFEnum("ofp_error_code", error_code_entries, {'wire_type': 'uint32_t'}))

        # We also need to patch the of_error_msg class to combine the 16-bit error
        # type and code fields into a single 32-bit error code field
        error_msg = find(lambda c: c.name == "of_error_msg", of_protocol.classes)
        if error_msg == None:
            raise Exception("of_error_msg class not found; OF version: " + str(version))
        err_type_index = None
        for i, member in enumerate(error_msg.members):
            if member.name == "err_type":
                # Keep track of the error type index so we can remove it once
                # we've finished iterating
                err_type_index = i
            elif member.name == 'code':
                # Change the code to be a 32-bit ofp_error_code enum value
                error_msg.members[i] = OFDataMember("code", "ofp_error_code")
        if err_type_index == None:
            raise Exception("err_type member of of_error_msg not found; OF version: " + str(version))
        del error_msg.members[err_type_index]


def gen_error_type(enum_entry):
    return "OFErrorType." + error_type_map[enum_entry.name]

class JavaModel(object):
    # registry for enums that should not be generated
    # set(${java_enum_name})
    enum_blacklist = set(("OFDefinitions", "OFPortNo",))
    # registry for enum *entry* that should not be generated
    # map: ${java_enum_name} -> set(${java_entry_entry_name})
    enum_entry_blacklist = defaultdict(lambda: set(), OFFlowWildcards=set([ "NW_DST_BITS", "NW_SRC_BITS", "NW_SRC_SHIFT", "NW_DST_SHIFT" ]))

    # registry of interfaces that should not be generated
    # set(java_names)
    # OFUint structs are there for god-knows what in loci. We certainly don't need them.
    interface_blacklist = set( ("OFUint8", "OFUint32",))
    # registry of interface properties that should not be generated
    # map: $java_type -> set(java_name_property)
    read_blacklist = defaultdict(lambda: set(), OFExperimenter=set(('data','subtype')), OFActionExperimenter=set(('data',)))
    # map: $java_type -> set(java_name_property)
    write_blacklist = defaultdict(lambda: set(), OFOxm=set(('typeLen',)), OFAction=set(('type',)), OFInstruction=set(('type',)), OFFlowMod=set(('command', )), OFExperimenter=set(('data','subtype')), OFActionExperimenter=set(('data',)))
    # interfaces that are virtual
    virtual_interfaces = set(['OFOxm', 'OFInstruction', 'OFFlowMod', 'OFBsnVport' ])

    OxmMapEntry = namedtuple("OxmMapEntry", ["type_name", "value", "masked" ])
    oxm_map = { "OFOxmInPort":              OxmMapEntry("OFPort", "IN_PORT", False),
                "OFOxmInPortMasked":        OxmMapEntry("OFPort", "IN_PORT", True),
                "OFOxmInPhyPort":           OxmMapEntry("OFPort", "IN_PHY_PORT", False),
                "OFOxmInPhyPortMasked":     OxmMapEntry("OFPort", "IN_PHY_PORT", True),
                "OFOxmMetadata":            OxmMapEntry("OFMetadata", "METADATA", False),
                "OFOxmMetadataMasked":      OxmMapEntry("OFMetadata", "METADATA", True),
                "OFOxmEthDst":              OxmMapEntry("MacAddress", "ETH_DST", False),
                "OFOxmEthDstMasked":        OxmMapEntry("MacAddress", "ETH_DST", True),
                "OFOxmEthSrc":              OxmMapEntry("MacAddress", "ETH_SRC", False),
                "OFOxmEthSrcMasked":        OxmMapEntry("MacAddress", "ETH_SRC", True),
                "OFOxmEthType":             OxmMapEntry("EthType", "ETH_TYPE", False),
                "OFOxmEthTypeMasked":       OxmMapEntry("EthType", "ETH_TYPE", True),
                "OFOxmVlanVid":             OxmMapEntry("VlanVid", "VLAN_VID", False),
                "OFOxmVlanVidMasked":       OxmMapEntry("VlanVid", "VLAN_VID", True),
                "OFOxmVlanPcp":             OxmMapEntry("VlanPcp", "VLAN_PCP", False),
                "OFOxmVlanPcpMasked":       OxmMapEntry("VlanPcp", "VLAN_PCP", True),
                "OFOxmIpDscp":              OxmMapEntry("IpDscp", "IP_DSCP", False),
                "OFOxmIpDscpMasked":        OxmMapEntry("IpDscp", "IP_DSCP", True),
                "OFOxmIpEcn":               OxmMapEntry("IpEcn", "IP_ECN", False),
                "OFOxmIpEcnMasked":         OxmMapEntry("IpEcn", "IP_ECN", True),
                "OFOxmIpProto":             OxmMapEntry("IpProtocol", "IP_PROTO", False),
                "OFOxmIpProtoMasked":       OxmMapEntry("IpProtocol", "IP_PROTO", True),
                "OFOxmIpv4Src":             OxmMapEntry("IPv4Address", "IPV4_SRC", False),
                "OFOxmIpv4SrcMasked":       OxmMapEntry("IPv4Address", "IPV4_SRC", True),
                "OFOxmIpv4Dst":             OxmMapEntry("IPv4Address", "IPV4_DST", False),
                "OFOxmIpv4DstMasked":       OxmMapEntry("IPv4Address", "IPV4_DST", True),
                "OFOxmTcpSrc":              OxmMapEntry("TransportPort", "TCP_SRC", False),
                "OFOxmTcpSrcMasked":        OxmMapEntry("TransportPort", "TCP_SRC", True),
                "OFOxmTcpDst":              OxmMapEntry("TransportPort", "TCP_DST", False),
                "OFOxmTcpDstMasked":        OxmMapEntry("TransportPort", "TCP_DST", True),
                "OFOxmUdpSrc":              OxmMapEntry("TransportPort", "UDP_SRC", False),
                "OFOxmUdpSrcMasked":        OxmMapEntry("TransportPort", "UDP_SRC", True),
                "OFOxmUdpDst":              OxmMapEntry("TransportPort", "UDP_DST", False),
                "OFOxmUdpDstMasked":        OxmMapEntry("TransportPort", "UDP_DST", True),
                "OFOxmSctpSrc":             OxmMapEntry("TransportPort", "SCTP_SRC", False),
                "OFOxmSctpSrcMasked":       OxmMapEntry("TransportPort", "SCTP_SRC", True),
                "OFOxmSctpDst":             OxmMapEntry("TransportPort", "SCTP_DST", False),
                "OFOxmSctpDstMasked":       OxmMapEntry("TransportPort", "SCTP_DST", True),
                "OFOxmIcmpv4Type":          OxmMapEntry("ICMPv4Type", "ICMPV4_TYPE", False),
                "OFOxmIcmpv4TypeMasked":    OxmMapEntry("ICMPv4Type", "ICMPV4_TYPE", True),
                "OFOxmIcmpv4Code":          OxmMapEntry("ICMPv4Code", "ICMPV4_CODE", False),
                "OFOxmIcmpv4CodeMasked":    OxmMapEntry("ICMPv4Code", "ICMPV4_CODE", True),
                "OFOxmArpOp":               OxmMapEntry("ArpOpcode", "ARP_OP", False),
                "OFOxmArpOpMasked":         OxmMapEntry("ArpOpcode", "ARP_OP", True),
                "OFOxmArpSpa":              OxmMapEntry("IPv4Address", "ARP_SPA", False),
                "OFOxmArpSpaMasked":        OxmMapEntry("IPv4Address", "ARP_SPA", True),
                "OFOxmArpTpa":              OxmMapEntry("IPv4Address", "ARP_TPA", False),
                "OFOxmArpTpaMasked":        OxmMapEntry("IPv4Address", "ARP_TPA", True),
                "OFOxmArpSha":              OxmMapEntry("MacAddress", "ARP_SHA", False),
                "OFOxmArpShaMasked":        OxmMapEntry("MacAddress", "ARP_SHA", True),
                "OFOxmArpTha":              OxmMapEntry("MacAddress", "ARP_THA", False),
                "OFOxmArpThaMasked":        OxmMapEntry("MacAddress", "ARP_THA", True),
                "OFOxmIpv6Src":             OxmMapEntry("IPv6Address", "IPV6_SRC", False),
                "OFOxmIpv6SrcMasked":       OxmMapEntry("IPv6Address", "IPV6_SRC", True),
                "OFOxmIpv6Dst":             OxmMapEntry("IPv6Address", "IPV6_DST", False),
                "OFOxmIpv6DstMasked":       OxmMapEntry("IPv6Address", "IPV6_DST", True),
                "OFOxmIpv6Flabel":          OxmMapEntry("IPv6FlowLabel", "IPV6_FLABEL", False),
                "OFOxmIpv6FlabelMasked":    OxmMapEntry("IPv6FlowLabel", "IPV6_FLABEL", True),
                "OFOxmIcmpv6Type":          OxmMapEntry("U8", "ICMPV6_TYPE", False),
                "OFOxmIcmpv6TypeMasked":    OxmMapEntry("U8", "ICMPV6_TYPE", True),
                "OFOxmIcmpv6Code":          OxmMapEntry("U8", "ICMPV6_CODE", False),
                "OFOxmIcmpv6CodeMasked":    OxmMapEntry("U8", "ICMPV6_CODE", True),
                "OFOxmIpv6NdTarget":        OxmMapEntry("IPv6Address", "IPV6_ND_TARGET", False),
                "OFOxmIpv6NdTargetMasked":  OxmMapEntry("IPv6Address", "IPV6_ND_TARGET", True),
                "OFOxmIpv6NdSll":           OxmMapEntry("MacAddress", "IPV6_ND_SLL", False),
                "OFOxmIpv6NdSllMasked":     OxmMapEntry("MacAddress", "IPV6_ND_SLL", True),
                "OFOxmIpv6NdTll":           OxmMapEntry("MacAddress", "IPV6_ND_TLL", False),
                "OFOxmIpv6NdTllMasked":     OxmMapEntry("MacAddress", "IPV6_ND_TLL", True),
                "OFOxmMplsLabel":           OxmMapEntry("U32", "MPLS_LABEL", False),
                "OFOxmMplsLabelMasked":     OxmMapEntry("U32", "MPLS_LABEL", True),
                "OFOxmMplsTc":              OxmMapEntry("U8", "MPLS_TC", False),
                "OFOxmMplsTcMasked":        OxmMapEntry("U8", "MPLS_TC", True),
                "OFOxmBsnInPortsMasked128": OxmMapEntry("OFPortMap", "BSN_IN_PORTS_MASKED_128", True)
                }

    # Registry of nullable properties:
    # ${java_class_name} -> set(${java_property_name})
    nullable_map = defaultdict(lambda: set(),
    )

    # represents a subgroup of a bitmask enum that is actualy a normal enumerable within a masked part of the enum
    # e.g., the flags STP.* in OF1.0 port state are bit mask entries, but instead enumerables according to the mask "STP_MASK"
    # name: a name for the group
    # mask: java name of the enum entry that defines the mask
    # members: set of names of the members of the group
    MaskedEnumGroup = namedtuple("MaskedEnumGroup", ("name", "mask", "members"))

    # registry of MaskedEnumGroups (see above).
    # map: ${java_enum_name}: tuple(MaskedEnumGroup)
    masked_enum_groups = defaultdict(lambda: (),
            OFPortState = (MaskedEnumGroup("stp_flags", mask="STP_MASK", members=set(("STP_LISTEN", "STP_LEARN", "STP_FORWARD", "STP_BLOCK"))), ),
            OFConfigFlags = (
                MaskedEnumGroup("frag_flags", mask="FRAG_MASK", members=set(("FRAG_NORMAL", "FRAG_DROP", "FRAG_REASM"))),
            ),
            OFTableConfig = (
                MaskedEnumGroup("table_miss_flags", mask="TABLE_MISS_MASK", members=set(("TABLE_MISS_CONTROLLER", "TABLE_MISS_CONTINUE", "TABLE_MISS_DROP"))),
            ),
    )

    # represents a metadata property associated with an EnumClass
    # name:
    class OFEnumPropertyMetadata(namedtuple("OFEnumPropertyMetadata", ("name", "type", "value"))):
        """
        represents a metadata property associated with an Enum Class
        @param name name of metadata property
        @param type java_type instance describing the type
        @value: Generator function f(entry) that generates the value
        """
        @property
        def variable_name(self):
            return self.name[0].lower() + self.name[1:]

        @property
        def getter_name(self):
            prefix = "is" if self.type == java_type.boolean else "get"
            return prefix+self.name

    """ Metadata container. """
    OFEnumMetadata = namedtuple("OFEnumMetadata", ("properties", "to_string"))

    def gen_port_speed(enum_entry):
        """ Generator function for OFortFeatures.PortSpeed"""
        splits = enum_entry.name.split("_")
        if len(splits)>=2:
            m = re.match(r'\d+[MGTP]B', splits[1])
            if m:
                return "PortSpeed.SPEED_{}".format(splits[1])
        return "PortSpeed.SPEED_NONE";

    def gen_stp_state(enum_entry):
        """ Generator function for OFPortState.StpState"""
        splits = enum_entry.name.split("_")
        if len(splits)>=1:
            if splits[0] == "STP":
                return "true"
        return "false"

    # registry for metadata properties for enums
    # map: ${java_enum_name}: OFEnumMetadata
    enum_metadata_map = defaultdict(lambda: JavaModel.OFEnumMetadata((), None),
            OFPortFeatures = OFEnumMetadata((OFEnumPropertyMetadata("PortSpeed", java_type.port_speed, gen_port_speed),), None),
            OFPortState = OFEnumMetadata((OFEnumPropertyMetadata("StpState", java_type.boolean, gen_stp_state),), None),
            OFErrorCode = OFEnumMetadata((OFEnumPropertyMetadata("ErrorType", java_type.error_type, gen_error_type),), None),
    )

    @property
    @memoize
    def versions(self):
        return OrderedSet( JavaOFVersion(raw_version) for raw_version in of_g.target_version_list )

    @property
    @memoize
    def interfaces(self):
        version_map_per_class = collections.OrderedDict()

        for raw_version, of_protocol in of_g.ir.items():
            jversion = JavaOFVersion(of_protocol.wire_version)

            for of_class in of_protocol.classes:
                if not of_class.name in version_map_per_class:
                    version_map_per_class[of_class.name] = collections.OrderedDict()

                version_map_per_class[of_class.name][jversion] = of_class

        interfaces = []
        for class_name, version_map in version_map_per_class.items():
            interfaces.append(JavaOFInterface(class_name, version_map))

        interfaces = [ i for i in interfaces if i.name not in self.interface_blacklist ]

        return interfaces

    @memoize
    def interface_by_name(self, name):
        return find(lambda i: erase_type_annotation(i.name) == erase_type_annotation(name), self.interfaces)

    @property
    @memoize
    def all_classes(self):
        return [clazz for interface in self.interfaces for clazz in interface.versioned_classes]

    @property
    @memoize
    def enums(self):
        name_version_enum_map = OrderedDefaultDict(lambda: OrderedDict())

        for version in self.versions:
            of_protocol = of_g.ir[version.int_version]
            for enum in of_protocol.enums:
                name_version_enum_map[enum.name][version] = enum

        enums = [ JavaEnum(name, version_enum_map) for name, version_enum_map,
                        in name_version_enum_map.items() ]

        # inelegant - need java name here
        enums = [ enum for enum in enums if enum.name not in self.enum_blacklist ]
        return enums

    @memoize
    def enum_by_name(self, name):
        res = find(lambda e: e.name == name, self.enums)
        if not res:
            raise KeyError("Could not find enum with name %s" % name)
        return res

    @property
    @memoize
    def of_factories(self):
        prefix = "org.projectfloodlight.openflow.protocol"

        factories = OrderedDict()

        sub_factory_classes = ("OFAction", "OFInstruction", "OFMeterBand", "OFOxm", "OFQueueProp")
        for base_class in sub_factory_classes:
            package = base_class[2:].lower()
            remove_prefix = base_class[2].lower() + base_class[3:]

            # HACK need to have a better way to deal with parameterized base classes
            annotated_base_class = base_class + "<?>" if base_class == "OFOxm" else base_class

            factories[base_class] = OFFactory(package="%s.%s" % (prefix, package),
                    name=base_class + "s", members=[], remove_prefix=remove_prefix, base_class=annotated_base_class, sub_factories={})

        factories[""] = OFFactory(
                    package=prefix,
                    name="OFFactory",
                    remove_prefix="",
                    members=[], base_class="OFMessage", sub_factories=OrderedDict(
                        ("{}{}s".format(n[2].lower(), n[3:]), "{}s".format(n)) for n in sub_factory_classes ))

        for i in self.interfaces:
            for n, factory in factories.items():
                if n == "":
                    factory.members.append(i)
                    break
                else:
                    super_class = self.interface_by_name(n)
                    if i.is_instance_of(super_class):
                        factory.members.append(i)
                        break
        return factories.values()

    def generate_class(self, clazz):
        """ return wether or not to generate implementation class clazz.
            Now true for everything except OFTableModVer10.
            @param clazz JavaOFClass instance
        """
        if clazz.interface.name.startswith("OFMatchV"):
            return True
        elif clazz.name == "OFTableModVer10":
            # tablemod ver 10 is a hack and has no oftype defined
            return False
        if loxi_utils.class_is_message(clazz.interface.c_name):
            return True
        if loxi_utils.class_is_oxm(clazz.interface.c_name):
            return True
        if loxi_utils.class_is_action(clazz.interface.c_name):
            return True
        if loxi_utils.class_is_instruction(clazz.interface.c_name):
            return True
        else:
            return True


class OFFactory(namedtuple("OFFactory", ("package", "name", "members", "remove_prefix", "base_class", "sub_factories"))):
    @property
    def factory_classes(self):
            return [ OFFactoryClass(
                    package="org.projectfloodlight.openflow.protocol.ver{}".format(version.of_version),
                    name="{}Ver{}".format(self.name, version.of_version),
                    interface=self,
                    version=version
                    ) for version in model.versions ]

    def method_name(self, member, builder=True):
        n = member.variable_name
        if n.startswith(self.remove_prefix):
            n = n[len(self.remove_prefix):]
            n = n[0].lower() + n[1:]
        if builder:
            return "build" + n[0].upper() + n[1:]
        else:
            return n

OFGenericClass = namedtuple("OFGenericClass", ("package", "name"))
class OFFactoryClass(namedtuple("OFFactoryClass", ("package", "name", "interface", "version"))):
    @property
    def base_class(self):
        return self.interface.base_class

    @property
    def versioned_base_class(self):
        base_class_interface = model.interface_by_name(self.interface.base_class)
        if base_class_interface and base_class_interface.has_version(self.version):
            return base_class_interface.versioned_class(self.version)
        else:
            return None

model = JavaModel()

#######################################################################
### OFVersion
#######################################################################

class JavaOFVersion(object):
    """ Models a version of OpenFlow. contains methods to convert the internal
        Loxi version to a java constant / a string """
    def __init__(self, int_version):
        self.int_version = int(int_version)

    @property
    def of_version(self):
        return "1" + str(int(self.int_version) - 1)

    @property
    def constant_version(self):
        return "OF_" + self.of_version

    def __repr__(self):
        return "JavaOFVersion(%d)" % self.int_version

    def __str__(self):
        return of_g.param_version_names[self.int_version]

    def __hash__(self):
        return hash(self.int_version)

    def __eq__(self, other):
        if other is None or type(self) != type(other):
            return False
        return (self.int_version,) == (other.int_version,)

#######################################################################
### Interface
#######################################################################

class JavaOFInterface(object):
    """ Models an OpenFlow Message class for the purpose of the java class.
        Version agnostic, in contrast to the loxi_ir python model.
    """
    def __init__(self, c_name, version_map):
        """"
        @param c_name: loxi style name (e.g., of_flow_add)
        @param version_map map of { JavaOFVersion: OFClass (from loxi_ir) }
        """
        self.c_name = c_name
        self.version_map = version_map
        # name: the Java Type name, e.g., OFFlowAdd
        self.name = java_type.name_c_to_caps_camel(c_name) if c_name != "of_header" else "OFMessage"
        # variable_name name to use for variables of this type. i.e., flowAdd
        self.variable_name = self.name[2].lower() + self.name[3:]
        self.title_name = self.variable_name[0].upper() + self.variable_name[1:]
        # name for use in constants: FLOW_ADD
        self.constant_name = c_name.upper().replace("OF_", "")

        pck_suffix, parent_interface, self.type_annotation = self.class_info()
        self.package = "org.projectfloodlight.openflow.protocol.%s" % pck_suffix if pck_suffix else "org.projectfloodlight.openflow.protocol"
        if self.name != parent_interface:
            self.parent_interface = parent_interface
        else:
            self.parent_interface = None

    @property
    @memoize
    def all_parent_interfaces(self):
        return [ "OFObject" ] + \
               ([ self.parent_interface ] if self.parent_interface else [] )+ \
               self.additional_parent_interfaces
    @property
    @memoize
    def additional_parent_interfaces(self):
        if loxi_utils.class_is_message(self.c_name) and not self.is_virtual:
            m = re.match(r'(.*)Request$', self.name)
            if m:
                reply_name = m.group(1) + "Reply"
                if model.interface_by_name(reply_name):
                    return ["OFRequest<%s>" % reply_name ]
        return []


    def is_instance_of(self, other_class):
        if self == other_class:
            return True
        parent = self.super_class
        if parent is None:
            return False
        else:
            return parent.is_instance_of(other_class)

    @property
    def super_class(self):
        if not self.parent_interface:
            return None
        else:
            return model.interface_by_name(self.parent_interface)


    def inherited_declaration(self, type_spec="?"):
        if self.type_annotation:
            return "%s<%s>" % (self.name, type_spec)
        else:
            return "%s" % self.name

    @property
    def type_variable(self):
        if self.type_annotation:
            return "<T>"
        else:
            return "";

    def class_info(self):
        """ return tuple of (package_prefix, parent_class) for the current JavaOFInterface"""
        # FIXME: This duplicates inheritance information that is now available in the loxi_ir
        # model (note, that the loxi model is on versioned classes). Should check/infer the
        # inheritance information from the versioned lox_ir classes.
        if re.match(r'OF.+StatsRequest$', self.name):
            return ("", "OFStatsRequest", None)
        elif re.match(r'OF.+StatsReply$', self.name):
            return ("", "OFStatsReply", None)
        elif re.match(r'OFFlow(Add|Modify(Strict)?|Delete(Strict)?)$', self.name):
            return ("", "OFFlowMod", None)
        elif loxi_utils.class_is_message(self.c_name) and re.match(r'OFBsn.+$', self.name) and self.name != "OFBsnHeader":
            return ("", "OFBsnHeader", None)
        elif loxi_utils.class_is_message(self.c_name) and re.match(r'OFNicira.+$', self.name) and self.name != "OFNiciraHeader":
            return ("", "OFNiciraHeader", None)
        elif self.name == "OFBsnHeader" or self.name =="OFNiciraHeader":
            return ("", "OFExperimenter", None)
        elif re.match(r'OFMatch.*', self.name):
            return ("", "Match", None)
        elif loxi_utils.class_is_message(self.c_name):
            return ("", "OFMessage", None)
        elif loxi_utils.class_is_action(self.c_name):
            if re.match(r'OFActionBsn.+', self.name):
                return ("action", "OFActionBsn", None)
            elif re.match(r'OFActionNicira.+', self.name):
                return ("action", "OFActionNicira", None)
            elif self.name == "OFActionBsn" or self.name == "OFActionNicira":
                return ("action", "OFActionExperimenter", None)
            else:
                return ("action", "OFAction", None)
        elif re.match(r'OFBsnVport.+$', self.name):
            return ("", "OFBsnVport", None)
        elif self.name == "OFOxm":
            return ("oxm", None, "T extends OFValueType<T>")
        elif loxi_utils.class_is_oxm(self.c_name):
            if self.name in model.oxm_map:
                return ("oxm", "OFOxm<%s>" % model.oxm_map[self.name].type_name, None)
            else:
                return ("oxm", "OFOxm", None)
        elif loxi_utils.class_is_instruction(self.c_name):
            return ("instruction", "OFInstruction", None)
        elif loxi_utils.class_is_meter_band(self.c_name):
            return ("meterband", "OFMeterBand", None)
        elif loxi_utils.class_is_queue_prop(self.c_name):
            return ("queueprop", "OFQueueProp", None)
        elif loxi_utils.class_is_hello_elem(self.c_name):
            return ("", "OFHelloElem", None)
        else:
            return ("", None, None)

    @property
    @memoize
    def writeable_members(self):
        return [ m for m in self.members if m.is_writeable ]

    @property
    @memoize
    def members(self):
        return self.ir_model_members + self.virtual_members

    @property
    @memoize
    def ir_model_members(self):
        """return a list of all members to be exposed by this interface. Corresponds to
           the union of the members of the vesioned classes without length, fieldlength
           and pads (those are handled automatically during (de)serialization and not exposed"""
        all_versions = []
        member_map = collections.OrderedDict()

        for (version, of_class) in self.version_map.items():
            for of_member in of_class.members:
                if isinstance(of_member, OFLengthMember) or \
                   isinstance(of_member, OFFieldLengthMember) or \
                   isinstance(of_member, OFPadMember):
                    continue
                if of_member.name not in member_map:
                    member_map[of_member.name] = JavaMember.for_of_member(self, of_member)

        return tuple(m for m in member_map.values() if m.name not in model.read_blacklist[self.name])

    @property
    def virtual_members(self):
        if self.name == "OFOxm":
            return (
                    JavaVirtualMember(self, "value", java_type.generic_t),
                    JavaVirtualMember(self, "mask", java_type.generic_t),
                    JavaVirtualMember(self, "matchField", java_type.make_match_field_jtype("T")),
                    JavaVirtualMember(self, "masked", java_type.boolean),
                   )
        elif self.parent_interface and self.parent_interface.startswith("OFOxm"):
            field_type = java_type.make_match_field_jtype(model.oxm_map[self.name].type_name) \
                if self.name in model.oxm_map \
                else java_type.make_match_field_jtype()

            return (
                    JavaVirtualMember(self, "matchField", field_type),
                    JavaVirtualMember(self, "masked", java_type.boolean),
                   ) \
                   + \
                   (
                           ( JavaVirtualMember(self, "mask", find(lambda x: x.name == "value", self.ir_model_members).java_type), ) if not find(lambda x: x.name == "mask", self.ir_model_members) else
                    ()
                   )
        else:
            return ()

    @property
    @memoize
    def is_virtual(self):
        """ Is this interface virtual. If so, do not generate a builder interface """
        return self.name in model.virtual_interfaces or all(ir_class.virtual for ir_class in self.version_map.values())

    @property
    def is_universal(self):
        """ Is this interface universal, i.e., does it exist in all OF versions? """
        return len(self.all_versions) == len(model.versions)

    @property
    @memoize
    def all_versions(self):
        """ return list of all versions that this interface exists in """
        return self.version_map.keys()

    def has_version(self, version):
        return version in self.version_map

    def versioned_class(self, version):
        return JavaOFClass(self, version, self.version_map[version])

    @property
    @memoize
    def versioned_classes(self):
            return [ self.versioned_class(version) for version in self.all_versions ]

#######################################################################
### (Versioned) Classes
#######################################################################

class JavaOFClass(object):
    """ Models an OpenFlow Message class for the purpose of the java class.
        Version specific child of a JavaOFInterface
    """
    def __init__(self, interface, version, ir_class):
        """
        @param interface JavaOFInterface instance of the parent interface
        @param version JavaOFVersion
        @param ir_class OFClass from loxi_ir
        """
        self.interface = interface
        self.ir_class = ir_class
        self.c_name = self.ir_class.name
        self.version = version
        self.constant_name = self.c_name.upper().replace("OF_", "")
        self.package = "org.projectfloodlight.openflow.protocol.ver%s" % version.of_version
        self.generated = False

    @property
    @memoize
    def unit_test(self):
        return JavaUnitTestSet(self)

    @property
    def name(self):
        return "%sVer%s" % (self.interface.name, self.version.of_version)

    @property
    def variable_name(self):
        return self.name[3:]

    @property
    def length(self):
        if self.is_fixed_length:
            return self.min_length
        else:
            raise Exception("No fixed length for class %s, version %s" % (self.name, self.version))

    @property
    def min_length(self):
        """ @return the minimum wire length of an instance of this class in bytes """
        id_tuple = (self.ir_class.name, self.version.int_version)
        return of_g.base_length[id_tuple] if id_tuple in of_g.base_length else -1

    @property
    def is_fixed_length(self):
        """ true iff this class serializes to a fixed length on the wire """
        return (self.ir_class.name, self.version.int_version) in of_g.is_fixed_length and \
                not self.is_virtual

    def all_properties(self):
        return self.interface.members

    def get_member(self, name):
        for m in self.members:
            if m.name == name:
                return m

    @property
    @memoize
    def data_members(self):
        return [ prop for prop in self.members if prop.is_data ]

    @property
    @memoize
    def fixed_value_members(self):
        return [ prop for prop in self.members if prop.is_fixed_value ]

    @property
    @memoize
    def public_members(self):
        return [ prop for prop in self.members if prop.is_public ]

    @property
    @memoize
    def members(self):
        return self.ir_model_members + self.virtual_members

    @property
    def ir_model_members(self):
        members = [ JavaMember.for_of_member(self, of_member) for of_member in self.ir_class.members ]
        return tuple(members)

    @property
    def virtual_members(self):
        if self.interface.parent_interface and self.interface.parent_interface.startswith("OFOxm"):
            if self.interface.name in model.oxm_map:
                oxm_entry = model.oxm_map[self.interface.name]
                return (
                    JavaVirtualMember(self, "matchField", java_type.make_match_field_jtype(oxm_entry.type_name), "MatchField.%s" % oxm_entry.value),
                    JavaVirtualMember(self, "masked", java_type.boolean, "true" if oxm_entry.masked else "false"),
                   )
            else:
                return (
                    JavaVirtualMember(self, "matchField", java_type.make_match_field_jtype(), "null"),
                    JavaVirtualMember(self, "masked", java_type.boolean, "false"),
                   )
        else:
            return ()

    def all_versions(self):
        return [ JavaOFVersion(int_version)
                 for int_version in of_g.unified[self.c_name]
                 if int_version != 'union' and int_version != 'object_id' ]

    def version_is_inherited(self, version):
        return 'use_version' in of_g.unified[self.ir_class.name][version.int_version]

    def inherited_from(self, version):
        return JavaOFVersion(of_g.unified[self.ir_class.name][version.int_version]['use_version'])

    @property
    def is_virtual(self):
        return self.ir_class.virtual # type_maps.class_is_virtual(self.c_name) or self.ir_class.virtual

    @property
    def discriminator(self):
        return find(lambda m: isinstance(m, OFDiscriminatorMember), self.ir_class.members)

    @property
    def is_extension(self):
        return type_maps.message_is_extension(self.c_name, -1)

    @property
    def align(self):
        return int(self.ir_class.params['align']) if 'align' in self.ir_class.params else 0

    @property
    @memoize
    def superclass(self):
        return find(lambda c: c.version == self.version and c.c_name == self.ir_class.superclass, model.all_classes)

    @property
    @memoize
    def subclasses(self):
        return [ c for c in model.all_classes if c.version == self.version and c.ir_class.superclass == self.c_name ]

#######################################################################
### Member
#######################################################################


class JavaMember(object):
    """ Models a property (member) of an openflow class. """
    def __init__(self, msg, name, java_type, member):
        self.msg = msg
        self.name = name
        self.java_type = java_type
        self.member = member
        self.c_name = self.member.name if(hasattr(self.member, "name")) else ""

    @property
    def title_name(self):
        return self.name[0].upper() + self.name[1:]

    @property
    def constant_name(self):
        return self.c_name.upper()

    @property
    def getter_name(self):
        return ("is" if self.java_type.public_type == "boolean" else "get") + self.title_name

    @property
    def setter_name(self):
        return "set" + self.title_name

    @property
    def default_name(self):
        if self.is_fixed_value:
            return self.constant_name
        else:
            return "DEFAULT_"+self.constant_name

    @property
    def default_value(self):
        if self.is_fixed_value:
            return self.enum_value
        else:
            default = self.java_type.default_op(self.msg.version)
            if default == "null" and not self.is_nullable:
                return None
            else:
                return default

    @property
    def enum_value(self):
        if self.name == "version":
            return "OFVersion.%s" % self.msg.version.constant_version

        java_type = self.java_type.public_type;
        try:
            global model
            enum = model.enum_by_name(java_type)
            entry = enum.entry_by_version_value(self.msg.version, self.value)
            return "%s.%s" % ( enum.name, entry.name)
        except KeyError, e:
            print e.message
            return self.value

    @property
    def is_pad(self):
        return isinstance(self.member, OFPadMember)

    def is_type_value(self, version=None):
        if(version==None):
            return any(self.is_type_value(version) for version in self.msg.all_versions)
        try:
            return self.c_name in get_type_values(self.msg.c_name, version.int_version)
        except:
            return False

    @property
    def is_field_length_value(self):
        return isinstance(self.member, OFFieldLengthMember)

    @property
    def is_discriminator(self):
        return isinstance(self.member, OFDiscriminatorMember)

    @property
    def is_length_value(self):
        return isinstance(self.member, OFLengthMember)

    @property
    def is_public(self):
        return not (self.is_pad or self.is_length_value)

    @property
    def is_data(self):
        return isinstance(self.member, OFDataMember) and self.name != "version"

    @property
    def is_fixed_value(self):
        return hasattr(self.member, "value") or self.name == "version" \
                or ( self.name == "length" and self.msg.is_fixed_length) \
                or ( self.name == "len" and self.msg.is_fixed_length)

    @property
    def value(self):
        if self.name == "version":
            return self.msg.version.int_version
        elif self.name == "length" or self.name == "len":
            return self.msg.length
        else:
            return self.java_type.format_value(self.member.value)

    @property
    def priv_value(self):
        if self.name == "version":
            return self.msg.version.int_version
        elif self.name == "length" or self.name == "len":
            return self.msg.length
        else:
            return self.java_type.format_value(self.member.value, pub_type=False)


    @property
    def is_writeable(self):
        return self.is_data and not self.name in model.write_blacklist[self.msg.name]

    def get_type_value_info(self, version):
        return get_type_values(msg.c_name, version.int_version)[self.c_name]

    @property
    def length(self):
        if hasattr(self.member, "length"):
            return self.member.length
        else:
            count, base = loxi_utils.type_dec_to_count_base(self.member.type)
            return of_g.of_base_types[base]['bytes'] * count

    @staticmethod
    def for_of_member(java_class, member):
        if isinstance(member, OFPadMember):
            return JavaMember(None, "", None, member)
        else:
            if member.name == 'len':
                name = 'length'
            elif member.name == 'value_mask':
                name = 'mask'
            else:
                name = java_type.name_c_to_camel(member.name)
            j_type = java_type.convert_to_jtype(java_class.c_name, member.name, member.oftype)
            return JavaMember(java_class, name, j_type, member)

    @property
    def is_universal(self):
        if not self.msg.c_name in of_g.unified:
            print("%s not self.unified" % self.msg.c_name)
            return False
        for version in of_g.unified[self.msg.c_name]:
            if version == 'union' or version =='object_id':
                continue
            if 'use_version' in of_g.unified[self.msg.c_name][version]:
                continue

            if not self.member.name in (f['name'] for f in of_g.unified[self.msg.c_name][version]['members']):
                return False
        return True

    @property
    def is_virtual(self):
        return False

    def __hash__(self):
        return hash(self.name)

    def __eq__(self, other):
        if other is None or type(self) != type(other):
            return False
        return (self.name,) == (other.name,)

    @property
    def is_nullable(self):
        return self.name in model.nullable_map[self.msg.name]


class JavaVirtualMember(JavaMember):
    """ Models a virtual property (member) of an openflow class that is not backed by a loxi ir member """
    def __init__(self, msg, name, java_type, value=None):
        JavaMember.__init__(self, msg, name, java_type, member=None)
        self._value = value

    @property
    def is_fixed_value(self):
        return True

    @property
    def value(self):
        return self._value

    @property
    def priv_value(self):
        return self._value


    @property
    def is_universal(self):
        return True

    @property
    def is_virtual(self):
        return True

#######################################################################
### Unit Test
#######################################################################

class JavaUnitTestSet(object):
    def __init__(self, java_class):
        self.java_class = java_class
        first_data_file_name = "of{version}/{name}.data".format(version=java_class.version.of_version,
                                                     name=java_class.c_name[3:])
        data_file_template = "of{version}/{name}.".format(version=java_class.version.of_version,
                                                     name=java_class.c_name[3:]) + "{i}.data"
        test_class_name = self.java_class.name + "Test"
        self.test_units = []
        if test_data.exists(first_data_file_name):
            self.test_units.append(JavaUnitTest(java_class, first_data_file_name, test_class_name))
        i = 1
        while test_data.exists(data_file_template.format(i=i)):
            self.test_units.append(JavaUnitTest(java_class, data_file_template.format(i=i), test_class_name + str(i)))
            i = i + 1

    @property
    def package(self):
        return self.java_class.package

    @property
    def has_test_data(self):
        return len(self.test_units) > 0

    @property
    def length(self):
        return len(self.test_units)

    def get_test_unit(self, i):
        return self.test_units[i]


class JavaUnitTest(object):
    def __init__(self, java_class, file_name=None, test_class_name=None):
        self.java_class = java_class
        if file_name is None:
            self.data_file_name = "of{version}/{name}.data".format(version=java_class.version.of_version,
                                                         name=java_class.c_name[3:])
        else:
            self.data_file_name = file_name
        if test_class_name is None:
            self.test_class_name = self.java_class.name + "Test"
        else:
            self.test_class_name = test_class_name

    @property
    def package(self):
        return self.java_class.package

    @property
    def name(self):
        return self.test_class_name

    @property
    def has_test_data(self):
        return test_data.exists(self.data_file_name)

    @property
    @memoize
    def test_data(self):
        return test_data.read(self.data_file_name)


#######################################################################
### Enums
#######################################################################

class JavaEnum(object):
    def __init__(self, c_name, version_enum_map):
        self.c_name = c_name

        if c_name == "of_stats_types":
            self.name = "OFStatsType"
        else:
            self.name   = "OF" + java_type.name_c_to_caps_camel("_".join(c_name.split("_")[1:]))

        # Port_features has constants that start with digits
        self.name_prefix = "PF_" if self.name == "OFPortFeatures" else ""

        self.version_enums = version_enum_map

        entry_name_version_value_map = OrderedDefaultDict(lambda: OrderedDict())
        for version, ir_enum in version_enum_map.items():
            for ir_entry in ir_enum.entries:
                entry_name_version_value_map[ir_entry.name][version] = ir_entry.value

        self.entries = [ JavaEnumEntry(self, name, version_value_map)
                         for (name, version_value_map) in entry_name_version_value_map.items() ]

        self.entries = [ e for e in self.entries if e.name not in model.enum_entry_blacklist[self.name] ]
        self.package = "org.projectfloodlight.openflow.protocol"

        self.metadata = model.enum_metadata_map[self.name]

    def wire_type(self, version):
        ir_enum = self.version_enums[version]
        if "wire_type" in ir_enum.params:
            return java_type.convert_enum_wire_type_to_jtype(ir_enum.params["wire_type"])
        else:
            return java_type.u8

    @property
    @memoize
    def is_bitmask(self):
        return any(ir_enum.is_bitmask for ir_enum in self.version_enums.values())

    @property
    def versions(self):
        return self.version_enums.keys()

    @memoize
    def entry_by_name(self, name):
        res = find(lambda e: e.name == name, self.entries)
        if res:
            return res
        else:
            raise KeyError("Enum %s: no entry with name %s" % (self.name, name))

    @memoize
    def entry_by_c_name(self, name):
        res = find(lambda e: e.c_name == name, self.entries)
        if res:
            return res
        else:
            raise KeyError("Enum %s: no entry with c_name %s" % (self.name, name))

    @memoize
    def entry_by_version_value(self, version, value):
        res = find(lambda e: e.values[version] == value if version in e.values else False, self.entries)
        if res:
            return res
        else:
            raise KeyError("Enum %s: no entry with version %s, value %s" % (self.name, version, value))

# values: Map JavaVersion->Value
class JavaEnumEntry(object):
    def __init__(self, enum, name, values):
        self.enum = enum
        self.name = enum.name_prefix + "_".join(name.split("_")[1:]).upper()
        self.values = values

    @property
    def constructor_params(self):
        return [ m.value(self) for m in self.enum.metadata.properties ]

    def has_value(self, version):
        return version in self.values

    def value(self, version):
        return self.values[version]

    def format_value(self, version):
        res = self.enum.wire_type(version).format_value(self.values[version])
        return res

    def all_values(self, versions, not_present=None):
        return [ self.values[version] if version in self.values else not_present for version in versions ]

    @property
    @memoize
    def masked_enum_group(self):
        group = find(lambda g: self.name in g.members, model.masked_enum_groups[self.enum.name])
        return group

    @property
    @memoize
    def is_mask(self):
        return any(self.name == g.mask for g in model.masked_enum_groups[self.enum.name])
