'''dossier.label.relation_label

.. This software is released under an MIT/X11 open source license.
   Copyright 2012-2015 Diffeo, Inc.
'''
from __future__ import absolute_import

import cbor
from collections import Container, Hashable
import logging
import time

import enum
from itertools import imap, ifilter
from total_ordering import total_ordering

from dossier.label.label import time_complement, LabelStore

logger = logging.getLogger(__name__)


class RelationStrength(enum.Enum):
    '''A human-assigned value for the relation type.

    NONE - these entities are not related in any meaningful way.
    UNKNOWN - the relationship between these entities are unknown.
    AKA - The two entities are the same (coreference).
    WEAK - The entities are related but not in a particularly interesting way.
    STRONG - The entities are strongly related.
    '''
    NONE = -1
    UNKNOWN = 0
    WEAK = 1
    STRONG = 2
    AKA = 3

    @property
    def is_positive(self):
        return (self == RelationStrength.WEAK or
                self == RelationStrength.STRONG or
                self == RelationStrength.AKA)

    @property
    def is_negative(self):
        return not self.is_positive

    def __lt__(self, other):
        if self.__class__ is other.__class__:
            return self.value < other.value
        return NotImplemented

    def __le__(self, other):
        if self.__class__ is other.__class__:
            return self.value <= other.value
        return NotImplemented

    def __gt__(self, other):
        if self.__class__ is other.__class__:
            return self.value > other.value

    def __ge__(self, other):
        if self.__class__ is other.__class__:
            return self.value >= other.value
        return NotImplemented

@total_ordering
class RelationLabel(Container, Hashable):
    '''An immutable unit of ground truth data for relationships.

    A ``RelationLabel`` is a statement saying that the item at
    :attr:`content_id1` is related to the item at
    :attr:`content_id2`. The statement was recorded by
    :attr:`annotator_id`, a string identifying a user, at
    :attr:`epoch_ticks`. The strength of the relationship is specified
    by :attr:`rel_strength`, which is of type :class:`RelationStrength`.

    On creation, the tuple is normalized such that `content_id1` is
    less than `content_id2`.

    RelationLabels are comparable, sortable, and hashable. The sort
    order compares the two content ids, the annotator id, the epoch
    ticks, and then rel_strength.

    .. attribute:: content_id1

       The first content ID

    .. attribute:: content_id2

       The second content ID