# 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__)


def java_class_name(c_name):
    return java_type.name_c_to_caps_camel(c_name) if c_name != "of_header" else "OFMessage"

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')),
        OFInstructionExperimenter=set(('data',)))
    # map: $java_type -> set(java_name_property)
    write_blacklist = defaultdict(
        lambda: set(),
        OFOxm=set(('typeLen',)),
        OFOxs=set(('typeLen',)),
        OFAction=set(('type',)),
        OFInstruction=set(('type',)),
        OFFlowMod=set(('command', )),
        OFExperimenter=set(('data','subtype')),
        OFActionExperimenter=set(('data',)),
        OFBsnTlv=set(('type',)))
    # interfaces that are virtual
    virtual_interfaces = set(['OFOxm', 'OFInstruction', 'OFFlowMod', 'OFBsnVport', 'OFOxs' ])

    # 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"))),
            ),
            OFGetConfigReply = (
                MaskedEnumGroup("flags", mask="OFP_FRAG_MASK", members=set(("FRAG_NORMAL", "FRAG_DROP", "FRAG_REASM"))),
            ),
            OFSetConfig = (
                MaskedEnumGroup("flags", mask="OFP_FRAG_MASK", members=set(("FRAG_NORMAL", "FRAG_DROP", "FRAG_REASM"))),
            ),
    )

    # 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())
        name_stable_map = {}

        for version in self.versions:
            logger.debug("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
                stable = (enum.params.get('stable') == 'True')

                logger.debug("Enum: %s stable: %s", enum.name, stable)

                if not enum.name in name_stable_map:
                    name_stable_map[enum.name] = stable
                else:
                    if name_stable_map[enum.name] != stable:
                        raise Exception("Inconsistent enum stability (should be caught " +\
                            " by IR)")

        enums = [ JavaEnum(name, name_stable_map[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", "OFErrorMsg", "OFActionId", "OFInstructionId", "OFBsnTlv", "OFOxs")
        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" or base_class == "OFOxs" 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= (base_class == "OFErrorMsg"))

        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
        if clazz.interface.name.startswith("OFStatV"):
            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
        if loxi_utils.class_is_oxs(clazz.interface.c_name):
            return True
        else:
            return True

    @property
    @memoize
    def oxm_map(self):
        OxmMapEntry = namedtuple("OxmMapEntry", ["type_name", "value", "masked" ])
        return OrderedDict( (oxm.name, OxmMapEntry(type_name=oxm.member_by_name("value").java_type.public_type,
                                       value=re.sub(r'^of_oxm_', r'', re.sub(r'_masked$', r'', oxm.ir_class.name)).upper(),
                                       masked=oxm.ir_class.name.endswith("_masked")))
                  for oxm in self.interfaces if oxm.ir_class.is_subclassof("of_oxm") )

    @property
    @memoize
    def oxs_map(self):
        OxsMapEntry = namedtuple("OxsMapEntry", ["type_name", "value", "masked" ])
        return OrderedDict( (oxs.name, OxsMapEntry(type_name=oxs.member_by_name("value").java_type.public_type,
                                       value=re.sub(r'^of_oxs_', r'', re.sub(r'_masked$', r'', oxs.ir_class.name)).upper(),
                                       masked=oxs.ir_class.name.endswith("_masked")))
                  for oxs in self.interfaces if oxs.ir_class.is_subclassof("of_oxs") )

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_class_name(self.c_name)
        # 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 ]
            elif self.name == "OFBundleCtrlMsg":
                reply_name = "OFBundleCtrlMsg"
                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 code could be cleaned up further. Maybe some of the exceptions
        # here could be folded into ir, or the type arithmetic specified in a more general
        # fashion
        def calc_package(i):
            if i.is_subclassof("of_error_msg"):
                return "errormsg"
            elif i.is_instanceof("of_action"):
                return "action"
            elif i.is_instanceof("of_action_id"):
                return "actionid"
            elif i.is_instanceof("of_instruction"):
                return "instruction"
            elif i.is_instanceof("of_instruction_id"):
                return "instructionid"
            elif i.is_instanceof("of_oxm"):
                return "oxm"
            elif i.is_instanceof("of_oxs"):
                return "oxs"
            elif i.is_instanceof("of_meter_band"):
                return "meterband"
            elif i.is_instanceof("of_queue_prop"):
                return "queueprop"
            elif i.is_instanceof("of_bsn_tlv"):
                return "bsntlv"
            else:
                return ""

        def calc_super_name(i):
            if re.match('of_match_.*', i.name):
                return "Match"
            elif re.match('of_stat_.*', i.name):
                return "Stat"
            else:
                ir_super_class = self.ir_class.superclass
                return java_class_name(ir_super_class.name) if ir_super_class else ""

        package = calc_package(self.ir_class)
        super_name = calc_super_name(self.ir_class)

        if self.name == "OFStatsRequest":
            # stats_requests are special because of their type annotation
            return (package, "OFMessage", "T extends OFStatsReply")
        elif self.ir_class.is_subclassof('of_stats_request'):
            # stats_request subclasses  are special because of their type annotation
            reply_name = re.sub(r'Request$', 'Reply', self.name)
            super_type_annotation = "T" if self.ir_class.virtual else reply_name

            type_annotation = "T extends {}".format(reply_name) if self.ir_class.virtual \
                    else ""

            return (package, "{}<{}>".format(super_name, super_type_annotation),
                    type_annotation)
        elif self.name == "OFOxm":
            return (package, None, "T extends OFValueType<T>")
        elif self.name == "OFOxs":
            return (package, None, "T extends OFValueType<T>")
        elif loxi_utils.class_is_oxm(self.c_name):
            # look up type from member value for OFValueType type annotation
            if self.member_by_name("value") is not None:
                return (package, "OFOxm<%s>" % self.member_by_name("value").java_type.public_type, None)
            else:
                return (package, "OFOxm", None)
        elif loxi_utils.class_is_oxs(self.c_name):
            # look up type from member value for OFValueType type annotation
            if self.member_by_name("value") is not None:
                return (package, "OFOxs<%s>" % self.member_by_name("value").java_type.public_type, None)
            else:
                return (package, "OFOxs", None)
        else:
            return (package, super_name, 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.name == "OFOxs":
            virtual_members += [
                    JavaVirtualMember(self, "value", java_type.generic_t),
                    JavaVirtualMember(self, "statField", java_type.make_stat_field_jtype("T")),
                   ]
        elif self.ir_class.is_subclassof("of_oxm"):
            value = find(lambda m: m.name=="value", self.ir_model_members)
            if value:
                field_type = java_type.make_match_field_jtype(value.java_type.public_type)
            else:
                field_type = 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(value.java_type.public_type),
                            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))
        elif self.ir_class.is_subclassof("of_oxs"):
            value = find(lambda m: m.name=="value", self.ir_model_members)
            if value:
                field_type = java_type.make_stat_field_jtype(value.java_type.public_type)
            else:
                field_type = java_type.make_stat_field_jtype()

            virtual_members += [
                    JavaVirtualMember(self, "statField", field_type),
                    JavaVirtualMember(self, "masked", java_type.boolean),
                    JavaVirtualMember(self, "canonical", java_type.make_oxs_jtype(value.java_type.public_type),
                            custom_template=lambda builder: "OFOxs{}_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))
        elif self.name =="OFErrorMsg":
            virtual_members += [ JavaVirtualMember(self, "data", java_type.error_cause_data) ]

        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.ir_class.is_subclassof("of_oxm"):
            value_member = find(lambda m: m.name, self.ir_model_members)
            if value_member:
                oxm_entry = model.oxm_map[self.interface.name]
                virtual_members += [
                    JavaVirtualMember(self, "matchField", java_type.make_match_field_jtype(value_member.java_type.public_type), "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"),
                 ]
        elif self.ir_class.is_subclassof("of_oxs"):
            value_member = find(lambda m: m.name, self.ir_model_members)
            if value_member:
                oxs_entry = model.oxs_map[self.interface.name]
                virtual_members += [
                    JavaVirtualMember(self, "statField", java_type.make_stat_field_jtype(value_member.java_type.public_type), "StatField.%s" % oxs_entry.value),
                    JavaVirtualMember(self, "masked", java_type.boolean, "true" if oxs_entry.masked else "false"),
                    ]
            else:
                virtual_members += [
                    JavaVirtualMember(self, "statField", java_type.make_stat_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:
            logger.debug("No enum found for type %s version %s value %s", java_type, self.msg.version, self.value)
            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 needs_setter(self):
        if self.is_writeable:
            return True
        super_class = self.msg.super_class
        if super_class:
            super_member = super_class.member_by_name(self.name)
            if super_member:
                return super_member.needs_setter
        return 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, stable, version_enum_map):
        self.c_name = c_name
        self.stable = stable

        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"

        static_metadata = model.enum_metadata_map[self.name]
        if self.stable:
            # need this to look up wire_type, which does not matter
            any_version = version_enum_map.keys()[0]
            # if this is a 'stable' enum, i.e., its value won't change, add
            # a "Metadata" (virtual) field "StableValue" to it that returns
            # its wirevalue.
            stable_value = JavaModel.OFEnumPropertyMetadata("StableValue",
                    self.wire_type(any_version),
                    value = lambda entry: entry.stable_value)

            self.metadata = JavaModel.OFEnumMetadata(
                              properties=static_metadata.properties + (stable_value, ),
                              to_string=static_metadata.to_string
                            )
        else:
            self.metadata = static_metadata

    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.type, 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
    def stable_value(self):
        if self.enum.stable:
            return self.values.values()[0]
        else:
            raise Exception("Enum {} not stable".format(self.enum.name))

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