# Copyright (C) 2003-2007, 2009, 2010 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

"""A simple Set class."""

class Set(object):
    """A simple set class.

    Sets are not in Python until 2.3, and rdata are not immutable so
    we cannot use sets.Set anyway.  This class implements subset of
    the 2.3 Set interface using a list as the container.

    @ivar items: A list of the items which are in the set
    @type items: list"""

    __slots__ = ['items']

    def __init__(self, items=None):
        """Initialize the set.

        @param items: the initial set of items
        @type items: any iterable or None
        """

        self.items = []
        if not items is None:
            for item in items:
                self.add(item)

    def __repr__(self):
        return "dns.simpleset.Set(%s)" % repr(self.items)

    def add(self, item):
        """Add an item to the set."""
        if not item in self.items:
            self.items.append(item)

    def remove(self, item):
        """Remove an item from the set."""
        self.items.remove(item)

    def discard(self, item):
        """Remove an item from the set if present."""
        try:
            self.items.remove(item)
        except ValueError:
            pass

    def _clone(self):
        """Make a (shallow) copy of the set.

        There is a 'clone protocol' that subclasses of this class
        should use.  To make a copy, first call your super's _clone()
        method, and use the object returned as the new instance.  Then
        make shallow copies of the attributes defined in the subclass.

        This protocol allows us to write the set algorithms that
        return new instances (e.g. union) once, and keep using them in
        subclasses.
        """

        cls = self.__class__
        obj = cls.__new__(cls)
        obj.items = list(self.items)
        return obj

    def __copy__(self):
        """Make a (shallow) copy of the set."""
        return self._clone()

    def copy(self):
        """Make a (shallow) copy of the set."""
        return self._clone()

    def union_update(self, other):
        """Update the set, adding any elements from other which are not
        already in the set.
        @param other: the collection of items with which to update the set
        @type other: Set object
        """
        if not isinstance(other, Set):
            raise ValueError('other must be a Set instance')
        if self is other:
            return
        for item in other.items:
            self.add(item)

    def intersection_update(self, other):
        """Update the set, removing any elements from other which are not
        in both sets.
        @param other: the collection of items with which to update the set
        @type other: Set object
        """
        if not isinstance(other, Set):
            raise ValueError('other must be a Set instance')
        if self is other:
            return
        # we make a copy of the list so that we can remove items from
        # the list without breaking the iterator.
        for item in list(self.items):
            if item not in other.items:
                self.items.remove(item)

    def difference_update(self, other):
        """Update the set, removing any elements from other which are in
        the set.
        @param other: the collection of items with which to update the set
        @type other: Set object
        """
        if not isinstance(other, Set):
            raise ValueError('other must be a Set instance')
        if self is other:
            self.items = []
        else:
            for item in other.items:
                self.discard(item)

    def union(self, other):
        """Return a new set which is the union of I{self} and I{other}.

        @param other: the other set
        @type other: Set object
        @rtype: the same type as I{self}
        """

        obj = self._clone()
        obj.union_update(other)
        return obj

    def intersection(self, other):
        """Return a new set which is the intersection of I{self} and I{other}.

        @param other: the other set
        @type other: Set object
        @rtype: the same type as I{self}
        """

        obj = self._clone()
        obj.intersection_update(other)
        return obj

    def difference(self, other):
        """Return a new set which I{self} - I{other}, i.e. the items
        in I{self} which are not also in I{other}.

        @param other: the other set
        @type other: Set object
        @rtype: the same type as I{self}
        """

        obj = self._clone()
        obj.difference_update(other)
        return obj

    def __or__(self, other):
        return self.union(other)

    def __and__(self, other):
        return self.intersection(other)

    def __add__(self, other):
        return self.union(other)

    def __sub__(self, other):
        return self.difference(other)

    def __ior__(self, other):
        self.union_update(other)
        return self

    def __iand__(self, other):
        self.intersection_update(other)
        return self

    def __iadd__(self, other):
        self.union_update(other)
        return self

    def __isub__(self, other):
        self.difference_update(other)
        return self

    def update(self, other):
        """Update the set, adding any elements from other which are not
        already in the set.
        @param other: the collection of items with which to update the set
        @type other: any iterable type"""
        for item in other:
            self.add(item)

    def clear(self):
        """Make the set empty."""
        self.items = []

    def __eq__(self, other):
        # Yes, this is inefficient but the sets we're dealing with are
        # usually quite small, so it shouldn't hurt too much.
        for item in self.items:
            if not item in other.items:
                return False
        for item in other.items:
            if not item in self.items:
                return False
        return True

    def __ne__(self, other):
        return not self.__eq__(other)

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

    def __iter__(self):
        return iter(self.items)

    def __getitem__(self, i):
        return self.items[i]

    def __delitem__(self, i):
        del self.items[i]

    def __getslice__(self, i, j):
        return self.items[i:j]

    def __delslice__(self, i, j):
        del self.items[i:j]

    def issubset(self, other):
        """Is I{self} a subset of I{other}?

        @rtype: bool
        """

        if not isinstance(other, Set):
            raise ValueError('other must be a Set instance')
        for item in self.items:
            if not item in other.items:
                return False
        return True

    def issuperset(self, other):
        """Is I{self} a superset of I{other}?

        @rtype: bool
        """

        if not isinstance(other, Set):
            raise ValueError('other must be a Set instance')
        for item in other.items:
            if not item in self.items:
                return False
        return True
