"""
eventing.py event and event tagging utility functions

"""
from __future__ import absolute_import, division, print_function

import sys
import os
import datetime
from collections.abc import Set  # both set and frozen set

# Import ioflo libs
from .sixing import *
from .odicting import odict
from .timing import iso8601, tuuid
from .consoling import getConsole

console = getConsole()

def tagify(tail=u'', head=u'', sep=u'.'):
    """
    Returns namespaced event tag string.
    Tag generated by joining with sep the head and tail in that order
    head and tail may be a string or a list, tuple, or Set of strings

    If head is a list, tuple or Set Then
        join with sep all elements of head individually
    Else
        join in whole as string prefix

    If tail is a list, tuple or Set Then
        join with sep all elements of tail individually
    Else
        join in whole as string suffix

    If either head or tail is empty then do not exhibit in tag

    """
    if isinstance(head, (list, tuple, Set)):  # list like so expand
        parts = list(head)
    else:  # string like so put in list
        parts = [head]
    if isinstance(tail, (list, tuple, Set)):  # listlike so extend parts
        parts.extend(tail)
    else:  # string like so append
        parts.append(tail)
    return sep.join([part for part in parts if part])

def eventify(tag, data=None, stamp=None, uid=None):
    """
    Returns new event with tag and  current timestamp and data if any
    Timestamp is iso 8601
        YYYY-MM-DDTHH:MM:SS.mmmmmm which is strftime '%Y-%m-%dT%H:%M:%S.%f'
    Adds uid field if provided
    if not provided data is empty odict
    """
    event = odict([(u'tag', tag),
                   (u'stamp', stamp if stamp is not None else iso8601()),
                   ])
    if uid is not None:
        event['uid'] = uid
    event['data'] = data if data is not None else odict()
    return event

def eventize(tag, stamp=None, uid=None, data=None, route=None):
    """
    Returns odict with fields suitable for event message

    tag is required and must be provided namespaced (dotted) string
    stamp is optional timestamp, if stamp is True then substitude iso8601 time stamp
    uid is optional unique id, if uid is True then substitute time unique identifier
    data is optional data odict, if data is True then substitute empty odict
    route is optional routing odict of form {src: tuple, dst: tuple}
    """
    event = odict(tag=tag)
    if stamp is not None:
        event["stamp"] = iso8601() if stamp is True else stamp
    if uid is not None:
        event['uid'] = tuuid() if uid is True else uid
    if data is  not None:
        event["data"] = odict() if data is True else data
    if route is not None:
        event["route"] = route
    return event
