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

from ..models import TAG_TYPE
from ..models import Tag, TagRelation, dfs_child_closure, dfs_parent_closure


def is_valid_tag_type(tag_type):
    o = object()
    return TAG_TYPE.getDesc(tag_type, o) is not o


class TagControl(object):

    @classmethod
    def get_tag(cls, pk):
        return Tag.objects.get(pk=pk)

    @classmethod
    def add_tag(cls, name, tag_type):
        # TODO: 目前到做法语意不明
        t, created = Tag.objects.get_or_create(name=name)
        if created:
            assert is_valid_tag_type(tag_type)
            t.tag_type = tag_type
            t.save()
        return t

    @classmethod
    def add_relation(cls, parent, child):
        TagRelation.add_relation(parent=parent, child=child)

    @classmethod
    def del_relation(cls, parent, child):
        TagRelation.del_relation(parent=parent, child=child)

    @classmethod
    def get_ancestors(cls, initial_set, exclude_init, tag_type=None, is_online_only=None):
        result = dfs_parent_closure(initial_set=initial_set, exclude_init=exclude_init, is_online_only=is_online_only).values()
        if tag_type is not None:
            assert is_valid_tag_type(tag_type)
            result = [tag for tag in result if tag.tag_type == tag_type]
        return result

    @classmethod
    def get_descendants(cls, initial_set, exclude_init, tag_type=None, is_online_only=None):
        result = dfs_child_closure(initial_set=initial_set, exclude_init=exclude_init, is_online_only=is_online_only).values()
        if tag_type is not None:
            assert is_valid_tag_type(tag_type)
            result = [tag for tag in result if tag.tag_type == tag_type]
        return result

