## List of mixed data types
#
# This is a list of data types which require special treatment
# because the underlying datatype has changed between versions.
# The main example is port which went from 16 to 32 bits.  We
# define per-version accessors for these types and those are
# used in place of the normal ones.
#
# The wire protocol number is used to identify versions.  For now,
# the value is the name of the type to use for that version
#
# This is the map between the external type (like of_port_no_t)
# which is used by customers of this code and the internal
# datatypes (like uint16_t) that appear on the wire for a
# particular version.
#
from collections import namedtuple
import logging

import loxi_front_end.frontend_ir as fe
import loxi_ir.ir

ofp_constants = dict(
    OF_MAX_TABLE_NAME_LEN = 32,
    OF_MAX_PORT_NAME_LEN  = 16,
    OF_ETH_ALEN = 6,
    OF_DESC_STR_LEN   = 256,
    OF_SERIAL_NUM_LEN = 32,
    OF_APP_CODE_LEN = 15 	
)


of_mixed_types = dict(
    of_port_no_t = {
        1: "uint16_t",
        2: "uint32_t",
        3: "uint32_t",
        4: "uint32_t",
        5: "uint32_t",
        "short_name":"port_no"
        },
    of_port_desc_t = {
        1: "of_port_desc_t",
        2: "of_port_desc_t",
        3: "of_port_desc_t",
        4: "of_port_desc_t",
        5: "of_port_desc_t",
        "short_name":"port_desc"
        },
    of_bsn_vport_t = {
        1: "of_bsn_vport_t",
        2: "of_bsn_vport_t",
        3: "of_bsn_vport_t",
        4: "of_bsn_vport_t",
        5: "of_bsn_vport_t",
        "short_name":"bsn_vport"
        },
    of_fm_cmd_t = { # Flow mod command went from u16 to u8
        1: "uint16_t",
        2: "uint8_t",
        3: "uint8_t",
        4: "uint8_t",
        5: "uint8_t",
        "short_name":"fm_cmd"
        },
    of_wc_bmap_t = { # Wildcard bitmap
        1: "uint32_t",
        2: "uint32_t",
        3: "uint64_t",
        4: "uint64_t",
        5: "uint64_t",
        "short_name":"wc_bmap"
        },
    of_match_bmap_t = { # Match bitmap
        1: "uint32_t",
        2: "uint32_t",
        3: "uint64_t",
        4: "uint64_t",
        5: "uint64_t",
        "short_name":"match_bmap"
        },
    of_match_t = { # Match object
        1: "of_match_v1_t",
        2: "of_match_v2_t",
        3: "of_match_v3_t",
        4: "of_match_v3_t",  # Currently uses same match as 1.2 (v3).
        5: "of_match_v3_t",  # Currently uses same match as 1.2 (v3).
        "short_name":"match"
        },
)

## basic lengths
of_base_lengths = dict(
    char     = (1, True),
    uint8_t  = (1, True),
    uint16_t = (2, True),
    uint32_t = (4, True),
    uint64_t = (8, True),
    of_mac_addr_t = (6, True),
    of_ipv4_t = (4, True),
    of_ipv6_t = (16, True),
    of_port_name_t = (ofp_constants["OF_MAX_PORT_NAME_LEN"], True),
    of_table_name_t = (ofp_constants["OF_MAX_TABLE_NAME_LEN"], True),
    of_desc_str_t = (ofp_constants["OF_DESC_STR_LEN"], True),
    of_serial_num_t = (ofp_constants["OF_SERIAL_NUM_LEN"], True),
    of_str64_t = (64, True),
    of_str32_t = (32, True),
    of_str6_t = (6, True),
    of_match_v1_t = (40, True),
    of_match_v2_t = (88, True),
    of_match_v3_t = (8, False),
    of_octets_t = (0, False),
    of_bitmap_128_t = (16, True),
    of_checksum_128_t = (16, True),
    of_app_code_t = (15,True),
    of_sig_id_t = (6, True),
    of_bitmap_256_t = (32, True),
    of_bitmap_512_t = (64, True),
    of_odu_sig_id_t = (16, True),
    of_och_sig_id_t = (6, True),
)

def type_dec_to_count_base(m_type):
    """
    Resolve a type declaration like uint8_t[4] to a count (4) and base_type
    (uint8_t)

    @param m_type The string type declaration to process
    """
    count = 1
    chk_ar = m_type.split('[')
    if len(chk_ar) > 1:
        count_str = chk_ar[1].split(']')[0]
        if count_str in ofp_constants:
            count = ofp_constants[count_str]
        else:
            count = int(count_str)
        base_type = chk_ar[0]
    else:
        base_type = m_type
    return count, base_type


LengthInfo = namedtuple("LengthInfo", ("offset", "base_length", "is_fixed_length"))

def calc_lengths(version, fe_class, existing_classes, existing_enums):
    offset_fixed = True
    offset = 0

    member_infos = {}
    for member in fe_class.members:
        member_offset = offset if offset_fixed else None

        if isinstance(member, fe.OFPadMember):
            member_base_length = member.length
            member_fixed_length = True
        else:
            m_type = member.oftype
            name = member.name

            member_base_length = 0
            if m_type.find("list(") == 0:
                member_fixed_length = False
            elif m_type.find("struct") == 0:
                raise Exception("Error: recursive struct found: {}, {}"
                                    .format(fe_class.name, name))
            elif m_type == "octets":
                member_fixed_length = False
            else:
                member_base_length, member_fixed_length = member_length(version, fe_class, member, existing_classes, existing_enums)

        if not member_fixed_length:
            offset_fixed = False

        member_infos[member] = LengthInfo(member_offset, member_base_length,
                member_fixed_length)
        offset += member_base_length

    base_length = offset
    fixed_length = offset_fixed if not fe_class.virtual else False
    return (base_length, fixed_length, member_infos)

def member_length(version, fe_class, fe_member, existing_classes, existing_enums):
    """
    return the length of an ir member.

    @return tuple (base_length, length_fixed)
    """
    count, base_type = type_dec_to_count_base(fe_member.oftype)

    if base_type in of_mixed_types:
        base_type = of_mixed_types[base_type][version.wire_version]

    base_class = base_type[:-2]
    if base_class in existing_classes:
        member_ir_class = existing_classes[base_class]
        bytes = member_ir_class.base_length
        length_fixed = member_ir_class.is_fixed_length
        if member_ir_class.has_external_alignment:
            bytes = (bytes + 7) & ~7
    else:
        if base_type in existing_enums:
            enum = existing_enums[base_type]
            base_type = enum.wire_type

        if base_type in of_base_lengths:
            bytes, length_fixed = of_base_lengths[base_type]
        else:
            raise Exception("Unknown type for {}.{}: {}".format(fe_class.name, fe_member.name, base_type))

    return (count * bytes), length_fixed
