from ..type.definition import (GraphQLInterfaceType, GraphQLList,
                               GraphQLNonNull, GraphQLObjectType,
                               GraphQLUnionType, is_abstract_type)


def is_equal_type(type_a, type_b):
    if type_a is type_b:
        return True

    if isinstance(type_a, GraphQLNonNull) and isinstance(type_b, GraphQLNonNull):
        return is_equal_type(type_a.of_type, type_b.of_type)

    if isinstance(type_a, GraphQLList) and isinstance(type_b, GraphQLList):
        return is_equal_type(type_a.of_type, type_b.of_type)

    return False


def is_type_sub_type_of(schema, maybe_subtype, super_type):
    if maybe_subtype is super_type:
        return True

    if isinstance(super_type, GraphQLNonNull):
        if isinstance(maybe_subtype, GraphQLNonNull):
            return is_type_sub_type_of(schema, maybe_subtype.of_type, super_type.of_type)
        return False
    elif isinstance(maybe_subtype, GraphQLNonNull):
        return is_type_sub_type_of(schema, maybe_subtype.of_type, super_type)

    if isinstance(super_type, GraphQLList):
        if isinstance(maybe_subtype, GraphQLList):
            return is_type_sub_type_of(schema, maybe_subtype.of_type, super_type.of_type)
        return False
    elif isinstance(maybe_subtype, GraphQLList):
        return False

    if is_abstract_type(super_type) and isinstance(
            maybe_subtype, GraphQLObjectType) and schema.is_possible_type(
            super_type, maybe_subtype):
        return True

    return False


def do_types_overlap(schema, t1, t2):
    # print 'do_types_overlap', t1, t2
    if t1 == t2:
        # print '1'
        return True

    if isinstance(t1, (GraphQLInterfaceType, GraphQLUnionType)):
        if isinstance(t2, (GraphQLInterfaceType, GraphQLUnionType)):
            # If both types are abstract, then determine if there is any intersection
            # between possible concrete types of each.
            s = any([schema.is_possible_type(t2, type) for type in schema.get_possible_types(t1)])
            # print '2',s
            return s
        # Determine if the latter type is a possible concrete type of the former.
        r = schema.is_possible_type(t1, t2)
        # print '3', r
        return r

    if isinstance(t2, (GraphQLInterfaceType, GraphQLUnionType)):
        t = schema.is_possible_type(t2, t1)
        # print '4', t
        return t

    # print '5'
    return False
