# coding=utf8
from __future__ import unicode_literals, absolute_import, print_function


from .. import accessor


class Type(object):

    @property
    def name(self):
        return self.__class__.__name__

    def __contains__(self, item):
        return self.contains(item)

    def contains(self, item):
        raise NotImplementedError

    def unify(self, chain, item):
        raise NotImplementedError

    def __str__(self):
        return self.name


class SimpleType(Type):

    def unify(self, chain, item):
        if not self.contains(item):
            raise accessor.Conflict(chain, self, item).exception


class ConstructedType(Type):

    def contains(self, item):
        try:
            self.unify(accessor.AccessorChain(), item)
        except accessor.ConflictException:
            return False
        else:
            return True

    def access(self, ac):
        raise NotImplementedError


class Bottom(SimpleType):

    @property
    def name(self):
        return 'Void'

    def contains(self, item):
        return isinstance(item, Bottom)


class Any(SimpleType):

    def contains(self, item):
        return True


class LiteralType(SimpleType):

    def to_python(self):
        raise NotImplementedError

