# -*- coding: utf-8 -*-

from django.db import models

from polynum.base.models import (Request, Transition, RoleAssociation)

from .. import utils

def get_entity_filter(user):
    ras = RoleAssociation.objects.filter(user=user).select_related('entity', 'role')
    q = [models.Q(left_bound__gte=ra.entity.left_bound,
            left_bound__lt=ra.entity.right_bound) for ra in ras]
    if not q:
        return models.Q(id=-1)
    return reduce(models.Q.__or__, q)

def get_workable_requests(user):
    '''Retrieve requests and their actions:
       - whose entity the user has a role over or is a child of an entity the
         user has a role over,
       - whose status the user has power to do some action upon;

       The return value is a queryset, with each request present as many times
       as their is actions that the user can do upon them. The action id and
       name are attached to the request object.

        >>> requests = get_workable_requests(user)
        >>> for request in requests:
                print request.action_id
                print request.action_name
    '''
    ras = RoleAssociation.objects.filter(user=user).select_related('entity', 'role')
    filters = [models.Q(status__visible_by=ra.role,
            entity__left_bound__gte=ra.entity.left_bound,
            entity__left_bound__lt=ra.entity.right_bound) for ra in ras]
    filters.append(models.Q(user=user))
    q = reduce(models.Q.__or__, filters)
    return Request.objects.filter(q).distinct()

@utils.cache_to_django(timeout=30)
def get_workflows(user, request):
    filters = []
    if request.entity is not None:
        filters.append(models.Q(source=request.status,
                role__roleassociation__user=user,
                role__roleassociation__entity__left_bound__lte=request.entity.left_bound,
                role__roleassociation__entity__right_bound__gte=request.entity.right_bound))
    if request.user == user:
       filters.append(models.Q(role__name='Demandeur', source_id=request.status_id))
    if filters:
        return Transition.objects.filter(reduce(models.Q.__or__, filters)).distinct()
    else:
        return Transition.objects.none()
