# Copyright 2017-present Open Networking Foundation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# 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 License for the specific language governing permissions and
# limitations under the License.
# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
# Copyright (c) 2011, 2012 Open Networking Foundation
# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
# See the file LICENSE.pyloxi which should have been included in the source distribution
# Automatically generated by LOXI from template util.py
# Do not modify

import struct
import loxi
import const
import common
import action
import instruction
import oxm
import action_id
import instruction_id
import meter_band

def pretty_mac(mac):
    return ':'.join(["%02x" % x for x in mac])

def pretty_ipv4(v):
    return "%d.%d.%d.%d" % ((v >> 24) & 0xFF, (v >> 16) & 0xFF, (v >> 8) & 0xFF, v & 0xFF)

def pretty_flags(v, flag_names):
    set_flags = []
    for flag_name in flag_names:
        flag_value = getattr(const, flag_name)
        if v & flag_value == flag_value:
            set_flags.append(flag_name)
        elif v & flag_value:
            set_flags.append('%s&%#x' % (flag_name, v & flag_value))
        v &= ~flag_value
    if v:
        set_flags.append("%#x" % v)
    return '|'.join(set_flags) or '0'


def pretty_port(v):
    named_ports = [(k,v2) for (k,v2) in const.__dict__.iteritems() if k.startswith('OFPP_')]
    for (k, v2) in named_ports:
        if v == v2:
            return k
    return v

def pack_port_no(value):
    return struct.pack("!L", value)

def unpack_port_no(reader):
    return reader.read("!L")[0]

def pack_fm_cmd(value):
    return struct.pack("!B", value)

def unpack_fm_cmd(reader):
    return reader.read("!B")[0]

def init_wc_bmap():
    return 0

def pack_wc_bmap(value):
    return struct.pack("!Q", value)

def unpack_wc_bmap(reader):
    return reader.read("!Q")[0]

def init_match_bmap():
    return 0

def pack_match_bmap(value):
    return struct.pack("!Q", value)

def unpack_match_bmap(reader):
    return reader.read("!Q")[0]

MASK64 = (1 << 64) - 1

def pack_bitmap_128(value):
    x = 0l
    for y in value:
        x |= 1 << y
    return struct.pack("!QQ", (x >> 64) & MASK64, x & MASK64)

def unpack_bitmap_128(reader):
    hi, lo = reader.read("!QQ")
    x = (hi << 64) | lo
    i = 0
    value = set()
    while x != 0:
        if x & 1 == 1:
            value.add(i)
        i += 1
        x >>= 1
    return value

def pack_bitmap_512(value):
    words = [0] * 8
    for v in value:
        assert v < 512
        words[7-v/64] |= 1 << (v % 64)
    return struct.pack("!8Q", *words)

def unpack_bitmap_512(reader):
    words = reader.read("!8Q")
    x = 0l
    for word in words:
        x <<= 64
        x |= word
    i = 0
    value = set()
    while x != 0:
        if x & 1 == 1:
            value.add(i)
        i += 1
        x >>= 1
    return value

def pack_checksum_128(value):
    return struct.pack("!QQ", (value >> 64) & MASK64, value & MASK64)

def unpack_checksum_128(reader):
    hi, lo = reader.read("!QQ")
    return (hi << 64) | lo

def bitmap_to_version(bitmaps):
    versions = [i * 32 + shift
                for i, bitmap in enumerate(bitmaps)
                for shift in range(31) if bitmap & (1 << shift)]
    return versions

def verify_version_support(msg,version_list):
    version_list_sup = bitmap_to_version([msg.elements[0].bitmaps[0].value])
    return any(i in version_list_sup for i in version_list)
