# Path: baroque/datastructures/bags.py
# class EventTypesBag:
#     """A type-aware collection of event types
# 
#     Args:
#         eventtypes (collection, optional): collection of :obj:`baroque.entities.eventtypes.EventType` items.
# 
#     """
#     def __init__(self, eventtypes=None):
#         self.types = set()
#         if eventtypes is not None:
#             self.add(eventtypes)
# 
#     def add(self, eventtypes):
#         """Adds a collection of eventtypes to this bag.
# 
#         Args:
#             `list` of (:obj:`baroque.entities.eventtypes.EventType`): the event types to be added
# 
#         Raises:
#             `AssertionError`: when the supplied arg is not a collection or its items are not :obj:`baroque.entities.eventtypes.EventType` instances or :obj:`baroque.entities.eventtypes.EventType` subclasses 
# 
#         """
#         assert not isinstance(eventtypes, str)
#         assert isinstance(eventtypes, collections.Iterable)
#         assert all([isinstance(et, EventType) or type(et) == type
#                     for et in eventtypes])
#         self.types.update(set([type(et) for et in eventtypes]))
# 
#     def __len__(self):
#         return len(self.types)
# 
#     def __iter__(self):
#         return (et for et in self.types)
# 
#     def __contains__(self, item):
#         return type(item) in self.types
# 
# Path: baroque/utils/timestamp.py
# TIME_FORMAT = '%Y-%m-%dT%H:%M:%SZ'
# def utc_now():
# def stringify(timestamp):


import uuid
import hashlib
import collections
from json import dumps
from baroque.datastructures.bags import EventTypesBag
from baroque.utils import timestamp as ts


class Topic:
    """A distribution channel where events of specific types can be published
    and can be seen by subscribers of the topic. Topic subscribers will attach
    a reactor to the topic, which will be fired whenever any event of the types
    that are supported by the topic is published on the topic itself.

    Args:
        name (str): the name of this topic
        eventtypes (collection): the :obj:`baroque.entities.eventtype.EventType` objects that characterize this topic
        description (str, optional): a description of this topic
        owner (str, optional): the owner of this topic
        tags (set, optional): the `set` of tags that describe this topic

    Raises:
        `AssertionError`: name or tags are `None` or have a wrong type

    """

    def __init__(self, name, eventtypes, description=None, owner=None,
                 tags=None):
        assert name is not None
        assert isinstance(name, str)
        self.name = name
        assert eventtypes is not None
        if len(eventtypes) != 0:
            self.types = EventTypesBag(eventtypes)
        else:

# Path: baroque/datastructures/bags.py
# class EventTypesBag:
#     """A type-aware collection of event types
# 
#     Args:
#         eventtypes (collection, optional): collection of :obj:`baroque.entities.eventtypes.EventType` items.
# 
#     """
#     def __init__(self, eventtypes=None):
#         self.types = set()
#         if eventtypes is not None:
#             self.add(eventtypes)
# 
#     def add(self, eventtypes):
#         """Adds a collection of eventtypes to this bag.
# 
#         Args:
#             `list` of (:obj:`baroque.entities.eventtypes.EventType`): the event types to be added
# 
#         Raises:
#             `AssertionError`: when the supplied arg is not a collection or its items are not :obj:`baroque.entities.eventtypes.EventType` instances or :obj:`baroque.entities.eventtypes.EventType` subclasses 
# 
#         """
#         assert not isinstance(eventtypes, str)
#         assert isinstance(eventtypes, collections.Iterable)
#         assert all([isinstance(et, EventType) or type(et) == type
#                     for et in eventtypes])
#         self.types.update(set([type(et) for et in eventtypes]))
# 
#     def __len__(self):
#         return len(self.types)
# 
#     def __iter__(self):
#         return (et for et in self.types)
# 
#     def __contains__(self, item):
#         return type(item) in self.types
# 
# Path: baroque/utils/timestamp.py
# TIME_FORMAT = '%Y-%m-%dT%H:%M:%SZ'
# def utc_now():
# def stringify(timestamp):


# Path: baroque/entities/topic.py
import uuid
import hashlib
import collections
from json import dumps
from baroque.datastructures.bags import EventTypesBag
from baroque.utils import timestamp as ts



class Topic:
    """A distribution channel where events of specific types can be published
    and can be seen by subscribers of the topic. Topic subscribers will attach
    a reactor to the topic, which will be fired whenever any event of the types
    that are supported by the topic is published on the topic itself.

    Args:
        name (str): the name of this topic
        eventtypes (collection): the :obj:`baroque.entities.eventtype.EventType` objects that characterize this topic
        description (str, optional): a description of this topic
        owner (str, optional): the owner of this topic
        tags (set, optional): the `set` of tags that describe this topic

    Raises:
        `AssertionError`: name or tags are `None` or have a wrong type

    """

    def __init__(self, name, eventtypes, description=None, owner=None,
                 tags=None):
        assert name is not None
        assert isinstance(name, str)
        self.name = name
        assert eventtypes is not None
        if len(eventtypes) != 0:
            self.types = EventTypesBag(eventtypes)
        else:

            self.types = EventTypesBag()