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

"""
Code generation

These functions extract data from the IR and render templates with it.
"""

from collections import namedtuple
from itertools import groupby
from StringIO import StringIO
import template_utils
from generic_utils import chunks
import loxi_globals
import loxi_ir.ir as ir
import util
import c_code_gen
import c_gen.of_g_legacy as of_g
import c_gen.type_maps as type_maps
import c_gen.c_type_maps as c_type_maps

CLASS_CHUNK_SIZE = 32

PushWireTypesData = namedtuple('PushWireTypesData',
    ['class_name', 'versioned_type_members'])
PushWireTypesMember = namedtuple('PushWireTypesMember',
    ['name', 'offset', 'length', 'value'])

def push_wire_types_data(uclass):
    if uclass.virtual or not uclass.has_type_members:
        return None

    # Generate a dict of version -> list of PushWireTypesMember
    type_members_by_version = {}
    for version, ofclass in sorted(uclass.version_classes.items()):
        pwtms = []
        for m in ofclass.members:
            if isinstance(m, ir.OFTypeMember):
                if m.name == "version" and m.value == version.wire_version:
                    # Special case for version
                    pwtms.append(PushWireTypesMember(m.name, m.offset, m.length, "obj->version"))
                else:
                    pwtms.append(PushWireTypesMember(m.name, m.offset, m.length, hex(m.value)))
        type_members_by_version[version] = pwtms

    # Merge versions with identical type members
    all_versions = sorted(type_members_by_version.keys())
    versioned_type_members = []
    for pwtms, versions in groupby(all_versions, type_members_by_version.get):
        versioned_type_members.append((pwtms, list(versions)))

    return PushWireTypesData(
        class_name=uclass.name,
        versioned_type_members=versioned_type_members)

ParseWireTypesData = namedtuple('ParseWireTypesData',
    ['class_name', 'versioned'])
ParseWireTypesVersion = namedtuple('ParseWireTypesVersion',
    ['discriminator', 'subclasses'])
ParseWireTypesSubclass = namedtuple('ParseWireTypesSubclass',
    ['class_name', 'value', 'virtual'])

def parse_wire_types_data(uclass):
    if not uclass.virtual:
        return None

    # Generate a dict of version -> ParseWireTypesVersion
    versioned = {}
    for version, ofclass in sorted(uclass.version_classes.items()):
        discriminator = ofclass.discriminator
        subclasses = [ParseWireTypesSubclass(class_name=subclass.name,
                                             value=subclass.member_by_name(discriminator.name).value,
                                             virtual=subclass.virtual)
                      for subclass in ofclass.protocol.classes if subclass.superclass and subclass.superclass.name == ofclass.name]

        subclasses.sort(key=lambda x: x.value)
        versioned[version] = ParseWireTypesVersion(discriminator=discriminator,
                                                   subclasses=subclasses)

    return ParseWireTypesData(class_name=uclass.name,
                              versioned=sorted(versioned.items()))

# Output multiple LOCI classes into each C file. This reduces the overhead of
# parsing header files, which takes longer than compiling the actual code
# for many classes. It also reduces the compiled code size.
def generate_classes(install_dir):
    for i, chunk in enumerate(chunks(loxi_globals.unified.classes, CLASS_CHUNK_SIZE)):
        with template_utils.open_output(install_dir, "loci/src/class%02d.c" % i) as out:
            for uclass in chunk:
                util.render_template(out, "class.c",
                    push_wire_types_data=push_wire_types_data(uclass),
                    parse_wire_types_data=parse_wire_types_data(uclass))
                # Append legacy generated code
                c_code_gen.gen_new_function_definitions(out, uclass.name)
                c_code_gen.gen_accessor_definitions(out, uclass.name)

# TODO remove header classes and use the corresponding class instead
def generate_header_classes(install_dir):
    for cls in of_g.standard_class_order:
        if cls.find("_header") < 0 or cls in ["of_header", "of_bsn_header", "of_nicira_header"]:
            continue
        with template_utils.open_output(install_dir, "loci/src/%s.c" % cls) as out:
            util.render_template(out, "class.c",
                push_wire_types_data=None,
                parse_wire_types_data=None)
            # Append legacy generated code
            c_code_gen.gen_new_function_definitions(out, cls)
            c_code_gen.gen_accessor_definitions(out, cls)

def generate_classes_header(install_dir):
    # Collect legacy code
    tmp = StringIO()
    c_code_gen.gen_struct_typedefs(tmp)
    c_code_gen.gen_new_function_declarations(tmp)
    c_code_gen.gen_accessor_declarations(tmp)
    c_code_gen.gen_generics(tmp)

    with template_utils.open_output(install_dir, "loci/inc/loci/loci_classes.h") as out:
        util.render_template(out, "loci_classes.h",
            legacy_code=tmp.getvalue())

def generate_lists(install_dir):
    for cls in of_g.ordered_list_objects:
        with template_utils.open_output(install_dir, "loci/src/%s.c" % cls) as out:
            util.render_template(out, "class.c",
                push_wire_types_data=None,
                parse_wire_types_data=None)
            # Append legacy generated code
            c_code_gen.gen_new_function_definitions(out, cls)
            c_code_gen.gen_list_accessors(out, cls)

def generate_strings(install_dir):
    object_id_strs = []
    object_id_strs.append("of_object")
    object_id_strs.extend(of_g.ordered_messages)
    object_id_strs.extend(of_g.ordered_non_messages)
    object_id_strs.extend(of_g.ordered_list_objects)
    object_id_strs.extend(of_g.ordered_pseudo_objects)
    object_id_strs.append("of_unknown_object")

    with template_utils.open_output(install_dir, "loci/src/loci_strings.c") as out:
        util.render_template(out, "loci_strings.c", object_id_strs=object_id_strs)

def generate_init_map(install_dir):
    with template_utils.open_output(install_dir, "loci/src/loci_init_map.c") as out:
        util.render_template(out, "loci_init_map.c", classes=of_g.standard_class_order)

def generate_type_maps(install_dir):
    # Collect legacy code
    tmp = StringIO()
    c_type_maps.gen_length_array(tmp)
    c_type_maps.gen_extra_length_array(tmp)

    with template_utils.open_output(install_dir, "loci/src/of_type_maps.c") as out:
        util.render_template(out, "of_type_maps.c", legacy_code=tmp.getvalue())

ClassMetadata = namedtuple('ClassMetadata',
    ['name', 'wire_length_get', 'wire_length_set', 'wire_type_get', 'wire_type_set'])

def generate_class_metadata(install_dir):
    with template_utils.open_output(install_dir, "loci/inc/loci/loci_class_metadata.h") as out:
        util.render_template(out, "loci_class_metadata.h")

    with template_utils.open_output(install_dir, "loci/src/loci_class_metadata.c") as out:
        class_metadata = []
        for uclass in loxi_globals.unified.classes:
            wire_length_get = 'NULL'
            wire_length_set = 'NULL'
            wire_type_get = 'NULL'
            wire_type_set = 'NULL'

            if uclass and not uclass.virtual and uclass.has_type_members:
                wire_type_set = '%s_push_wire_types' % uclass.name

            if uclass.is_message and uclass.name != "of_header":
                wire_length_get = 'of_object_message_wire_length_get'
                wire_length_set = 'of_object_message_wire_length_set'
            elif uclass.is_action:
                wire_length_set = 'of_tlv16_wire_length_set'
                wire_length_get = 'of_tlv16_wire_length_get'
                wire_type_get = 'of_action_wire_object_id_get'
            elif uclass.is_instanceof('of_bsn_vport'):
                wire_length_set = 'of_tlv16_wire_length_set'
                wire_length_get = 'of_tlv16_wire_length_get'
                wire_type_get = 'of_bsn_vport_wire_object_id_get'
            elif uclass.is_action_id:
                wire_length_set = 'of_tlv16_wire_length_set'
                wire_length_get = 'of_tlv16_wire_length_get'
                wire_type_get = 'of_action_id_wire_object_id_get'
            elif uclass.is_instruction:
                wire_length_set = 'of_tlv16_wire_length_set'
                wire_length_get = 'of_tlv16_wire_length_get'
                wire_type_get = 'of_instruction_wire_object_id_get'
            elif uclass.is_instanceof('of_instruction_id'):
                wire_length_set = 'of_tlv16_wire_length_set'
                wire_length_get = 'of_tlv16_wire_length_get'
                wire_type_get = 'of_instruction_id_wire_object_id_get'
            elif uclass.is_instanceof('of_queue_prop'):
                wire_length_set = 'of_tlv16_wire_length_set'
                wire_length_get = 'of_tlv16_wire_length_get'
                wire_type_get = 'of_queue_prop_wire_object_id_get'
            elif uclass.is_instanceof('of_table_feature_prop'):
                wire_length_set = 'of_tlv16_wire_length_set'
                wire_length_get = 'of_tlv16_wire_length_get'
                wire_type_get = 'of_table_feature_prop_wire_object_id_get'
            elif uclass.is_instanceof('of_meter_band'):
                wire_length_set = 'of_tlv16_wire_length_set'
                wire_length_get = 'of_tlv16_wire_length_get'
                wire_type_get = 'of_meter_band_wire_object_id_get'
            elif uclass.is_instanceof('of_hello_elem'):
                wire_length_set = 'of_tlv16_wire_length_set'
                wire_length_get = 'of_tlv16_wire_length_get'
                wire_type_get = 'of_hello_elem_wire_object_id_get'
            elif uclass.is_instanceof('of_bsn_tlv'):
                wire_length_set = 'of_tlv16_wire_length_set'
                wire_length_get = 'of_tlv16_wire_length_get'
                wire_type_get = 'of_bsn_tlv_wire_object_id_get'
            elif uclass.is_oxm:
                wire_length_get = 'of_oxm_wire_length_get'
                wire_type_get = 'of_oxm_wire_object_id_get'
            elif uclass.name == "of_packet_queue":
                wire_length_get = 'of_packet_queue_wire_length_get'
                wire_length_set = 'of_packet_queue_wire_length_set'
            elif uclass.name == "of_meter_stats":
                wire_length_get = 'of_meter_stats_wire_length_get'
                wire_length_set = 'of_meter_stats_wire_length_set'
            elif uclass.name in ["of_group_desc_stats_entry", "of_group_stats_entry",
                   "of_flow_stats_entry", "of_bucket", "of_table_features",
                   "of_bsn_port_counter_stats_entry", "of_bsn_vlan_counter_stats_entry",
                   "of_bsn_gentable_entry_desc_stats_entry", "of_bsn_gentable_entry_stats_entry",
                   "of_bsn_gentable_desc_stats_entry"]:
                wire_length_get = "of_u16_len_wire_length_get"
                wire_length_set = "of_u16_len_wire_length_set"
            elif uclass.name == 'of_match_v3':
                wire_length_set = 'of_tlv16_wire_length_set'
                wire_length_get = 'of_tlv16_wire_length_get'
                wire_type_set = 'of_match_v3_push_wire_types'

            class_metadata.append(ClassMetadata(
                name=uclass.name,
                wire_length_get=wire_length_get,
                wire_length_set=wire_length_set,
                wire_type_get=wire_type_get,
                wire_type_set=wire_type_set))

        class_metadata.extend([
            ClassMetadata(
                name="of_action_header",
                wire_length_set='of_tlv16_wire_length_set',
                wire_length_get='of_tlv16_wire_length_get',
                wire_type_get='of_action_wire_object_id_get',
                wire_type_set='NULL'),
            ClassMetadata(
                name="of_action_id_header",
                wire_length_set='of_tlv16_wire_length_set',
                wire_length_get='of_tlv16_wire_length_get',
                wire_type_get='of_action_id_wire_object_id_get',
                wire_type_set='NULL'),
            ClassMetadata(
                name="of_bsn_vport_header",
                wire_length_set='of_tlv16_wire_length_set',
                wire_length_get='of_tlv16_wire_length_get',
                wire_type_get='of_bsn_vport_wire_object_id_get',
                wire_type_set='NULL'),
            ClassMetadata(
                name="of_instruction_header",
                wire_length_set='of_tlv16_wire_length_set',
                wire_length_get='of_tlv16_wire_length_get',
                wire_type_get='of_instruction_wire_object_id_get',
                wire_type_set='NULL'),
            ClassMetadata(
                name="of_instruction_id_header",
                wire_length_set='of_tlv16_wire_length_set',
                wire_length_get='of_tlv16_wire_length_get',
                wire_type_get='of_instruction_id_wire_object_id_get',
                wire_type_set='NULL'),
            ClassMetadata(
                name="of_queue_prop_header",
                wire_length_set='of_tlv16_wire_length_set',
                wire_length_get='of_tlv16_wire_length_get',
                wire_type_get='of_queue_prop_wire_object_id_get',
                wire_type_set='NULL'),
            ClassMetadata(
                name="of_table_feature_prop_header",
                wire_length_set='of_tlv16_wire_length_set',
                wire_length_get='of_tlv16_wire_length_get',
                wire_type_get='of_table_feature_prop_wire_object_id_get',
                wire_type_set='NULL'),
            ClassMetadata(
                name="of_meter_band_header",
                wire_length_set='of_tlv16_wire_length_set',
                wire_length_get='of_tlv16_wire_length_get',
                wire_type_get='of_meter_band_wire_object_id_get',
                wire_type_set='NULL'),
            ClassMetadata(
                name="of_hello_elem_header",
                wire_length_set='of_tlv16_wire_length_set',
                wire_length_get='of_tlv16_wire_length_get',
                wire_type_get='of_hello_elem_wire_object_id_get',
                wire_type_set='NULL'),
            ClassMetadata(
                name="of_bsn_tlv_header",
                wire_length_set='of_tlv16_wire_length_set',
                wire_length_get='of_tlv16_wire_length_get',
                wire_type_get='of_bsn_tlv_wire_object_id_get',
                wire_type_set='NULL'),
            ClassMetadata(
                name="of_oxm_header",
                wire_length_set='NULL',
                wire_length_get='of_oxm_wire_length_get',
                wire_type_get='of_oxm_wire_object_id_get',
                wire_type_set='NULL'),
        ])

        util.render_template(out, "loci_class_metadata.c", class_metadata=class_metadata)
