from django.db import models
from django.contrib.auth.models import User
from django.utils import timezone
from django.core.urlresolvers import reverse

from .assignment import Assignment
from .submission import Submission

class Course(models.Model):
    title = models.CharField(max_length=200)
    created = models.DateTimeField(auto_now_add=True, editable=False)
    owner = models.ForeignKey(User, related_name='courses', help_text="Only this user can change the course details and create new assignments.")
    tutors = models.ManyToManyField(User, blank=True, related_name='courses_tutoring', help_text="These users can edit / grade submissions for the course.")
    homepage = models.URLField(max_length=200, verbose_name="Course description link")
    active = models.BooleanField(default=True, help_text="Only assignments and submissions of active courses are shown to students and tutors. Use this flag for archiving past courses.")
    max_authors = models.PositiveSmallIntegerField(default=1, help_text="Maximum number of authors (= group size) for assignments in this course.")
    lti_key = models.CharField(max_length=100, null=True, blank=True, help_text="Key to be used by an LTI consumer when accessing this course.")
    lti_secret = models.CharField(max_length=100, null=True, blank=True, help_text="Secret to be used by an LTI consumer when accessing this course.")

    class Meta:
        app_label = 'opensubmit'

    def __unicode__(self):
        return unicode(self.title)

    def open_assignments(self):
        qs = Assignment.objects.filter(hard_deadline__gt=timezone.now())
        qs = qs.filter(publish_at__lt=timezone.now())
        qs = qs.filter(course=self)
        qs = qs.order_by('soft_deadline').order_by('hard_deadline').order_by('title')
        return qs

    def gradable_submissions(self):
        '''
            Queryset for the gradable submissions that are worth a look by tutors.
        '''
        qs = self._valid_submissions()
        qs = qs.filter(state__in=[Submission.GRADING_IN_PROGRESS, Submission.SUBMITTED_TESTED, Submission.TEST_FULL_FAILED, Submission.SUBMITTED])
        return qs

    def graded_submissions(self):
        '''
            Queryset for the graded submissions, which are worth closing.
        '''
        qs = self._valid_submissions().filter(state__in=[Submission.GRADED])
        return qs

    def grading_url(self):
        '''
            Determines the teacher backend link to the filtered list of gradable submissions for this course.
        '''
        grading_url="%s?coursefilter=%u&statefilter=tobegraded"%(
                            reverse('teacher:opensubmit_submission_changelist'),
                            self.pk
                        )
        return grading_url


    def authors(self):
        '''
            Queryset for all distinct authors this course had so far. Important for statistics.
            Note that this may be different from the list of people being registered for the course,
            f.e. when they submit something and the leave the course.
        '''
        qs = self._valid_submissions().values_list('authors',flat=True).distinct()
        return qs

    def _valid_submissions(self):
        qs = Submission.objects.filter(assignment__course=self).exclude(state=Submission.WITHDRAWN)
        return qs

def lti_secret(key):
    '''
        Consumer function as expected by blti package.
    '''
    try:
        return Course.objects.get(lti_key=key).lti_secret
    except:
        return None
