# 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
from loxi_globals import OFVersions
import loxi_globals
from loxi_ir import *
import loxi_utils.loxi_utils as loxi_utils
import test_data

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

logger = logging.getLogger(__name__)

class JavaModel(object):
    # registry for enums that should not be generated
    # set(${java_enum_name})
    enum_blacklist = set(("OFDefinitions", "OFPortNo", "OFVlanId", "OFGroup"))
    # 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',)),
        OFExperimenterStatsRequest=set(('data','subtype')),
        OFExperimenterStatsReply=set(('data','subtype')))
    # 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("OFVlanVidMatch", "VLAN_VID", False),
                "OFOxmVlanVidMasked":       OxmMapEntry("OFVlanVidMatch", "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),
                "OFOxmBsnInPorts128":       OxmMapEntry("OFBitMask128", "BSN_IN_PORTS_128", False),
                "OFOxmBsnInPorts128Masked": OxmMapEntry("OFBitMask128", "BSN_IN_PORTS_128", True),
                "OFOxmBsnLagId":            OxmMapEntry("LagId", "BSN_LAG_ID", False),
                "OFOxmBsnLagIdMasked":      OxmMapEntry("LagId", "BSN_LAG_ID", True),
                "OFOxmBsnVrf":              OxmMapEntry("VRF", "BSN_VRF", False),
                "OFOxmBsnVrfMasked":        OxmMapEntry("VRF", "BSN_VRF", True),
                "OFOxmBsnGlobalVrfAllowed":          OxmMapEntry("OFBooleanValue", "BSN_GLOBAL_VRF_ALLOWED", False),
                "OFOxmBsnGlobalVrfAllowedMasked":    OxmMapEntry("OFBooleanValue", "BSN_GLOBAL_VRF_ALLOWED", True),
                "OFOxmBsnL3InterfaceClassId":        OxmMapEntry("ClassId", "BSN_L3_INTERFACE_CLASS_ID", False),
                "OFOxmBsnL3InterfaceClassIdMasked":  OxmMapEntry("ClassId", "BSN_L3_INTERFACE_CLASS_ID", True),
                "OFOxmBsnL3SrcClassId":              OxmMapEntry("ClassId", "BSN_L3_SRC_CLASS_ID", False),
                "OFOxmBsnL3SrcClassIdMasked":        OxmMapEntry("ClassId", "BSN_L3_SRC_CLASS_ID", True),
                "OFOxmBsnL3DstClassId":              OxmMapEntry("ClassId", "BSN_L3_DST_CLASS_ID", False),
                "OFOxmBsnL3DstClassIdMasked":        OxmMapEntry("ClassId", "BSN_L3_DST_CLASS_ID", 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),
    )

    @property
    @memoize
    def versions(self):
        return OrderedSet( JavaOFVersion(ir_version) for ir_version in OFVersions.target_versions)

    @property
    @memoize
    def interfaces(self):
        interfaces = [ JavaOFInterface(ir_class) for ir_class in loxi_globals.unified.classes ]
        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:
            logger.info("version: {}".format(version.ir_version))
            of_protocol = loxi_globals.ir[version.ir_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={}, xid_generator=False)

        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 ),
                    xid_generator=True)

        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()

    @memoize
    def factory_of(self, interface):
        for factory in self.of_factories:
            if interface in factory.members:
                return factory
        return None

    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", "xid_generator"))):
    @property
    def factory_classes(self):
            return [ OFFactoryClass(
                    package="org.projectfloodlight.openflow.protocol.ver{}".format(version.dotless_version),
                    name="{}Ver{}".format(self.name, version.dotless_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

    def of_version(self, version):
        for fc in self.factory_classes:
            if fc.version == version:
                return fc
        return None

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, ir_version):
        assert isinstance(ir_version, OFVersion)
        self.ir_version = ir_version
        self.int_version = self.ir_version.wire_version

    @property
    def dotless_version(self):
        return self.ir_version.version.replace(".", "")

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

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

    def __str__(self):
        return self.ir_version.version

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

    def __eq__(self, other):
        if other is None or type(self) != type(other):
            return False
        return (self.ir_version,) == (other.ir_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, ir_class):
        """"
        @param c_name: loxi style name (e.g., of_flow_add)
        @param version_map map of { JavaOFVersion: OFClass (from loxi_ir) }
        """
        self.ir_class = ir_class
        self.c_name = ir_class.name
        self.version_map = { JavaOFVersion(v): c for v,c in ir_class.version_classes.items() }
        # name: the Java Type name, e.g., OFFlowAdd
        self.name = java_type.name_c_to_caps_camel(self.c_name) if self.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 = self.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'OFStatsRequest$', self.name):
            return ("", "OFMessage", "T extends OFStatsReply")
        elif self.ir_class.is_subclassof('of_stats_request'):
            if self.ir_class.is_subclassof('of_bsn_stats_request'):
                return ("", "OFBsnStatsRequest", None)
            elif self.ir_class.is_subclassof('of_experimenter_stats_request'):
                return ("", "OFExperimenterStatsRequest", None)
            else:
                return ("", "OFStatsRequest<{}>".format(re.sub(r'Request$', 'Reply', self.name)), None)
        elif self.ir_class.is_subclassof('of_stats_reply'):
            if self.ir_class.is_subclassof('of_bsn_stats_reply'):
                return ("", "OFBsnStatsReply", None)
            elif self.ir_class.is_subclassof('of_experimenter_stats_reply'):
                return ("", "OFExperimenterStatsReply", None)
            else:
                return ("", "OFStatsReply", None)
        elif self.ir_class.is_subclassof('of_error_msg'):
            return ("", "OFErrorMsg", None)
        elif self.ir_class.is_subclassof('of_flow_mod'):
            return ("", "OFFlowMod", None)
        elif self.ir_class.is_subclassof('of_group_mod'):
            return ("", "OFGroupMod", None)
        elif self.ir_class.is_subclassof('of_bsn_header'):
            return ("", "OFBsnHeader", None)
        elif self.ir_class.is_subclassof('of_nicira_header'):
            return ("", "OFNiciraHeader", None)
        elif self.ir_class.is_subclassof('of_experimenter'):
            return ("", "OFExperimenter", None)
        elif re.match(r'OFMatch.*', self.name):
            return ("", "Match", None)
        elif self.ir_class.is_message:
            return ("", "OFMessage", None)
        elif self.ir_class.is_action:
            if self.ir_class.is_subclassof('of_action_bsn'):
                return ("action", "OFActionBsn", None)
            elif self.ir_class.is_subclassof('of_action_nicira'):
                return ("action", "OFActionNicira", None)
            elif self.ir_class.is_subclassof('of_action_experimenter'):
                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)
        elif loxi_utils.class_is_table_feature_prop(self.c_name):
            return ("", "OFTableFeatureProp", None)
        else:
            return ("", None, None)

    @property

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

    @memoize
    def member_by_name(self, name):
        return find(lambda m: m.name == name, self.members)

    @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()

        member_version_map = {}
        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
                java_member = JavaMember.for_of_member(self, of_member)
                if of_member.name not in member_map:
                    member_map[of_member.name] = java_member
                    member_version_map[of_member.name] = version
                else:
                    existing = member_map[of_member.name]

                    if existing.java_type.public_type != java_member.java_type.public_type:
                        raise Exception(
                             "Error constructing interface {}: type signatures do not match up between versions.\n"
                             " Member Name: {}\n"
                             " Existing: Version={}, Java={}, IR={}\n"
                             " New:      Version={}, Java={}, IR={}"
                               .format(self.name, existing.name,
                                   member_version_map[of_member.name], existing.java_type.public_type, existing.member.oftype,
                                   version, java_member.java_type.public_type, java_member.member.oftype)
                        )

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

    @property
    def virtual_members(self):
        virtual_members = []
        if self.name == "OFOxm":
            virtual_members += [
                    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),
                    JavaVirtualMember(self, "canonical", java_type.make_oxm_jtype("T"))
                   ]
        elif self.ir_class.is_subclassof("of_oxm"):
            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()

            virtual_members += [
                    JavaVirtualMember(self, "matchField", field_type),
                    JavaVirtualMember(self, "masked", java_type.boolean),
                    JavaVirtualMember(self, "canonical", java_type.make_oxm_jtype(model.oxm_map[self.name].type_name),
                            custom_template=lambda builder: "OFOxm{}_getCanonical.java".format(".Builder" if builder else "")),
                   ]
            if not find(lambda x: x.name == "mask", self.ir_model_members):
                virtual_members.append(
                        JavaVirtualMember(self, "mask", find(lambda x: x.name == "value", self.ir_model_members).java_type))

        if not find(lambda m: m.name == "version", self.ir_model_members):
            virtual_members.append(JavaVirtualMember(self, "version", java_type.of_version))

        return tuple(virtual_members)

    @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.dotless_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.dotless_version)

    @property
    def variable_name(self):
        return self.name[2].lower() + 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 """
        return self.ir_class.base_length

    @property
    def is_fixed_length(self):
        """ true iff this class serializes to a fixed length on the wire """
        return self.ir_class.is_fixed_length and not self.is_virtual

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

    @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
    @memoize
    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):
        virtual_members = []
        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]
                virtual_members += [
                    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:
                virtual_members += [
                    JavaVirtualMember(self, "matchField", java_type.make_match_field_jtype(), "null"),
                    JavaVirtualMember(self, "masked", java_type.boolean, "false"),
                 ]
        if not find(lambda m: m.name == "version", self.ir_model_members):
            virtual_members.append(JavaVirtualMember(self, "version", java_type.of_version, "OFVersion.%s" % self.version.constant_version))

        return tuple(virtual_members)

    @memoize
    def member_by_name(self, name):
        return find(lambda m: m.name == name, self.members)

    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
    def length_includes_align(self):
        return self.ir_class.params['length_includes_align'] == "True" if 'length_includes_align' in self.ir_class.params else False

    @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
                   and c.ir_class.superclass.name == 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.java_type.format_value(self.msg.version.int_version, pub_type=False)
        elif self.name == "length" or self.name == "len":
            return self.java_type.format_value(self.msg.length, pub_type=False)
        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'
            elif member.name == 'group_id':
                name = 'group'
            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):
        for version, ir_class in self.msg.ir_class.version_classes.items():
            if not ir_class.member_by_name(self.member.name):
                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, custom_template=None):
        JavaMember.__init__(self, msg, name, java_type, member=None)
        self._value = value
        self.custom_template = custom_template

    @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.dotless_version,
                                                     name=java_class.c_name[3:])
        glob_file_name = "of{version}/{name}__*.data".format(version=java_class.version.dotless_version,
                                                     name=java_class.c_name[3:])
        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
        for f in test_data.glob(glob_file_name):
            m = re.match(".*__(.*).data", f)
            if m:
                suffix = java_type.name_c_to_caps_camel(m.group(1))
            else:
                suffix = str(i)
                i += 1
            test_class_name = self.java_class.name + suffix + "Test"
            self.test_units.append(JavaUnitTest(java_class, f, test_class_name))

    @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.dotless_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 interface(self):
        return self.java_class.interface
    
    @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

        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])
