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

"""
@brief Generic utilities

Intended to be imported into another namespace
"""

import functools
import sys
import of_g


################################################################
#
# Configuration related
#
################################################################

def config_check(str, dictionary = of_g.code_gen_config):
    """
    Return config value if in dictionary; else return False.
    @param str The lookup index
    @param dictionary The dict to check; use code_gen_config if None
    """

    if str in dictionary:
        return dictionary[str]

    return False

################################################################
#
# Debug
#
################################################################

def debug(obj):
    """
    Debug output to the current both the log file and debug output
    @param out_str The stringified output to write
    """
    of_g.loxigen_dbg_file.write(str(obj) + "\n")
    log(obj)

def log(obj):
    """
    Log output to the current global log file
    @param out_str The stringified output to write
    """
    of_g.loxigen_log_file.write(str(obj) + "\n")

################################################################
#
# Memoize
#
################################################################

def memoize(obj):
    """ A function/method decorator that memoizes the result"""
    cache = obj.cache = {}

    @functools.wraps(obj)
    def memoizer(*args, **kwargs):
        key = str(args) + str(kwargs)
        if key not in cache:
            cache[key] = obj(*args, **kwargs)
        return cache[key]
    return memoizer

################################################################
#
# OrderedSet
#
################################################################

import collections

class OrderedSet(collections.MutableSet):
    """
    A set implementations that retains insertion order.  From the receipe
    http://code.activestate.com/recipes/576694/
    as referred to in the python documentation
    """

    def __init__(self, iterable=None):
        self.end = end = []
        end += [None, end, end]         # sentinel node for doubly linked list
        self.map = {}                   # key --> [key, prev, next]
        if iterable is not None:
            self |= iterable

    def __len__(self):
        return len(self.map)

    def __contains__(self, key):
        return key in self.map

    def add(self, key):
        if key not in self.map:
            end = self.end
            curr = end[1]
            curr[2] = end[1] = self.map[key] = [key, curr, end]

    def discard(self, key):
        if key in self.map:
            key, prev, next = self.map.pop(key)
            prev[2] = next
            next[1] = prev

    def __iter__(self):
        end = self.end
        curr = end[2]
        while curr is not end:
            yield curr[0]
            curr = curr[2]

    def __reversed__(self):
        end = self.end
        curr = end[1]
        while curr is not end:
            yield curr[0]
            curr = curr[1]

    def pop(self, last=True):
        if not self:
            raise KeyError('set is empty')
        key = self.end[1][0] if last else self.end[2][0]
        self.discard(key)
        return key

    def __repr__(self):
        if not self:
            return '%s()' % (self.__class__.__name__,)
        return '%s(%r)' % (self.__class__.__name__, list(self))

    def __eq__(self, other):
        if isinstance(other, OrderedSet):
            return len(self) == len(other) and list(self) == list(other)
        return set(self) == set(other)

def find(iterable, func):
    """
    find the first item in iterable for which func returns something true'ish.
    @raise KeyError if no item in iterable fulfills the condition
    """
    for i in iterable:
        if func(i):
            return i
    raise KeyError("Couldn't find value that matches: %s" % repr(func))
