# Path: apps/taxonomy/models.py
# class Edge(models.Model):
#     ancestor = models.ForeignKey(TaxonNode, related_name='parent')
#     descendant = models.ForeignKey(TaxonNode, related_name='child')
#     length = models.IntegerField()
# 
# class TraversalOrder(models.Model):
#     current = models.ForeignKey(TaxonNode, related_name='current_taxon')
#     previous = models.ForeignKey(TaxonNode, related_name='previous_taxon')
#     next = models.ForeignKey(TaxonNode, related_name='next_taxon')
#     order_type = models.CharField(default='pre', max_length=31)
# 
#     @staticmethod
#     def create(previous_taxon_id, current_id):
#         parent_traversal_node = TraversalOrder.objects.get(current_id=previous_taxon_id)
#         if previous_taxon_id != parent_traversal_node.next_id:
#             next_traversal_node = TraversalOrder.objects.get(current_id=parent_traversal_node.next_id)
#         else:
#             next_traversal_node = parent_traversal_node
# 
#         new_traversal_node = TraversalOrder(
#             current_id=current_id,
#             next_id=next_traversal_node.current_id,
#             previous_id=parent_traversal_node.current_id,
#         )
# 
#         parent_traversal_node.next_id = current_id
#         next_traversal_node.previous_id = current_id
# 
#         new_traversal_node.save()
#         parent_traversal_node.save()
#         if previous_taxon_id != parent_traversal_node.next_id:
#             next_traversal_node.save()
# 
#     def remove(self):
#         next_traversal_node = TraversalOrder.objects.get(current_id=self.next)
#         previous_traversal_node = TraversalOrder.objects.get(current_id=self.previous)
# 
#         next_traversal_node.previous = previous_traversal_node.current
#         next_traversal_node.save()
# 
#         previous_traversal_node.next = next_traversal_node.current
#         previous_traversal_node.save()
# 
#         self.delete()
# 
# class Tree(models.Model):
#     name = models.CharField(max_length=255)
#     origin_tree = models.ForeignKey('self', related_name='origin', null=True, blank=True)
#     root_node = models.ForeignKey('TaxonNode', related_name='root', null=True, blank=True)  # on trees that hold the whole tree
#     owner_id = models.IntegerField(null=True)
#     created_by = models.IntegerField(null=True)
#     created_at = models.DateTimeField(auto_now_add=True, editable=True, blank=True)
#     updated_by = models.IntegerField(null=True)
#     updated_at = models.DateTimeField(blank=True, default='2000-01-01 00:00:00+03:00')
#     is_public = models.BooleanField(default=False)
#     is_deleted = models.BooleanField(default=False)
# 
#     def create_root_node(self):
#         self.root_node = TaxonNode(epithet=self.name,
#                                    taxon_rank_id=0
#                                    )
#         self.root_node.save()
#         self.root_node.create_edges(parent=None)
#         self.root_node_id = self.root_node.pk
#         self.save()
# 
#     def get_root_children(self):
#         """
#         Return first level children for root node
#         """
#         children_ids = [edge.descendant_id for edge in Edge.objects.filter(ancestor=self.root_node, length=1)]
#         return TaxonNode.objects.filter(pk__in=children_ids)
# 
#     def get_taxon_count(self):
#         return TaxonNode.objects.filter(tree=self).count()
# 
#     def clone_starting_from_taxon_node(self, starting_root_node):
#         TreeCloner.clone(self, starting_root_node)
# 
#     def __unicode__(self):
#         return u"%s" % (self.name)


from django.core.management.base import BaseCommand
from apps.taxonomy.models import Edge, TraversalOrder, Tree
    For creating traversal orders list must contain one single node that
    is the same node as args for this method. Also last_node must be the
    same node
    """
    def create_traversal_order(self, node_id, previous, next):
        traversal_node = TraversalOrder(current_id=node_id, previous_id=previous.current_id, next_id=previous.next_id)
        traversal_node.save()
        # update next nodes previous value
        next.previous_id = node_id
        next.save()
        # update previous nodes next value
        previous.next_id = node_id
        previous.save()

        # exclude non-current taxonnodes
        children = Edge.objects.filter(ancestor_id=node_id, length=1).filter(descendant_id__valid_name=None)

        if children.count() > 0:
            # => this cmd does not reverse the list of objects, should be list of ids instead
            children_ids = [child.descendant_id for child in children]
            children_ids.reverse()
            self.node_id_list = self.node_id_list + children_ids

        return traversal_node

    def handle(self, *args, **options):
        if len(args):
            trees = Tree.objects.filter(pk=args[0])
            can_proceed = True
        else:

# Path: apps/taxonomy/models.py
# class Edge(models.Model):
#     ancestor = models.ForeignKey(TaxonNode, related_name='parent')
#     descendant = models.ForeignKey(TaxonNode, related_name='child')
#     length = models.IntegerField()
# 
# class TraversalOrder(models.Model):
#     current = models.ForeignKey(TaxonNode, related_name='current_taxon')
#     previous = models.ForeignKey(TaxonNode, related_name='previous_taxon')
#     next = models.ForeignKey(TaxonNode, related_name='next_taxon')
#     order_type = models.CharField(default='pre', max_length=31)
# 
#     @staticmethod
#     def create(previous_taxon_id, current_id):
#         parent_traversal_node = TraversalOrder.objects.get(current_id=previous_taxon_id)
#         if previous_taxon_id != parent_traversal_node.next_id:
#             next_traversal_node = TraversalOrder.objects.get(current_id=parent_traversal_node.next_id)
#         else:
#             next_traversal_node = parent_traversal_node
# 
#         new_traversal_node = TraversalOrder(
#             current_id=current_id,
#             next_id=next_traversal_node.current_id,
#             previous_id=parent_traversal_node.current_id,
#         )
# 
#         parent_traversal_node.next_id = current_id
#         next_traversal_node.previous_id = current_id
# 
#         new_traversal_node.save()
#         parent_traversal_node.save()
#         if previous_taxon_id != parent_traversal_node.next_id:
#             next_traversal_node.save()
# 
#     def remove(self):
#         next_traversal_node = TraversalOrder.objects.get(current_id=self.next)
#         previous_traversal_node = TraversalOrder.objects.get(current_id=self.previous)
# 
#         next_traversal_node.previous = previous_traversal_node.current
#         next_traversal_node.save()
# 
#         previous_traversal_node.next = next_traversal_node.current
#         previous_traversal_node.save()
# 
#         self.delete()
# 
# class Tree(models.Model):
#     name = models.CharField(max_length=255)
#     origin_tree = models.ForeignKey('self', related_name='origin', null=True, blank=True)
#     root_node = models.ForeignKey('TaxonNode', related_name='root', null=True, blank=True)  # on trees that hold the whole tree
#     owner_id = models.IntegerField(null=True)
#     created_by = models.IntegerField(null=True)
#     created_at = models.DateTimeField(auto_now_add=True, editable=True, blank=True)
#     updated_by = models.IntegerField(null=True)
#     updated_at = models.DateTimeField(blank=True, default='2000-01-01 00:00:00+03:00')
#     is_public = models.BooleanField(default=False)
#     is_deleted = models.BooleanField(default=False)
# 
#     def create_root_node(self):
#         self.root_node = TaxonNode(epithet=self.name,
#                                    taxon_rank_id=0
#                                    )
#         self.root_node.save()
#         self.root_node.create_edges(parent=None)
#         self.root_node_id = self.root_node.pk
#         self.save()
# 
#     def get_root_children(self):
#         """
#         Return first level children for root node
#         """
#         children_ids = [edge.descendant_id for edge in Edge.objects.filter(ancestor=self.root_node, length=1)]
#         return TaxonNode.objects.filter(pk__in=children_ids)
# 
#     def get_taxon_count(self):
#         return TaxonNode.objects.filter(tree=self).count()
# 
#     def clone_starting_from_taxon_node(self, starting_root_node):
#         TreeCloner.clone(self, starting_root_node)
# 
#     def __unicode__(self):
#         return u"%s" % (self.name)


# Path: apps/taxonomy/management/commands/populate_pre_traversal.py
from django.core.management.base import BaseCommand
from apps.taxonomy.models import Edge, TraversalOrder, Tree

    For creating traversal orders list must contain one single node that
    is the same node as args for this method. Also last_node must be the
    same node
    """
    def create_traversal_order(self, node_id, previous, next):
        traversal_node = TraversalOrder(current_id=node_id, previous_id=previous.current_id, next_id=previous.next_id)
        traversal_node.save()
        # update next nodes previous value
        next.previous_id = node_id
        next.save()
        # update previous nodes next value
        previous.next_id = node_id
        previous.save()

        # exclude non-current taxonnodes
        children = Edge.objects.filter(ancestor_id=node_id, length=1).filter(descendant_id__valid_name=None)

        if children.count() > 0:
            # => this cmd does not reverse the list of objects, should be list of ids instead
            children_ids = [child.descendant_id for child in children]
            children_ids.reverse()
            self.node_id_list = self.node_id_list + children_ids

        return traversal_node

    def handle(self, *args, **options):
        if len(args):
            trees = Tree.objects.filter(pk=args[0])
            can_proceed = True
        else:

            can_proceed = len(TraversalOrder.objects.all()) == 0