from local_conf import LLL1
import importlib
oahpa_module = importlib.import_module(LLL1+'_oahpa')
settings = oahpa_module.settings
URL_PREFIX = settings.URL_PREFIX
hst = settings.hostname

from django.template import RequestContext
from django.http import HttpResponseRedirect, HttpResponseForbidden, Http404

from django.conf import settings
from .models import Goal, UserGoalInstance


def render_to_response(*args, **kwargs):
    """ Append an attribute onto the response so that we can grab the context
    from it in the track decorator. It has to be an attribute so that it
    doesn't depend on the function returning the response to be decorated by
    @trackGrade to get proper output. """

    #from django.shortcuts import render_to_response
    from django.shortcuts import render

    #response = render_to_response(*args, **kwargs)
    response = render(*args, **kwargs)
    response.context = args[2]

    return response

from django.contrib.auth.decorators import login_required

from models import UserProfile, Course, UserGrade, Activity

def trackGrade(gamename, request, c):
    """ Takes a name of the game, request, and the context, and produces
        a course grade entry for the student.

        In the corresponding oahpa.drills.views, first import this function

            ex.)    from courses.views import trackGrade

        Then, insert the following into each view before the return render_to_response

            ex.)    trackGrade('Morfa', request, c)
                    return render_to_response( etc ... )

        The first value is the name of the game, but this function handles
        the rest of choosing specifics, so course grade entries will display:

                Morfa - N-ILL - Bisyllabic
                Morfa - PRS - Trisyllabic
    """
    try:
        SETTINGS = c['settingsform'].data
    except TypeError:
        return

    if c['show_correct'] == 1 or c['all_correct'] == 1:
        if request.user.is_authenticated() and not request.user.is_anonymous():
            game_type = ''
            if 'gamename_key' in c['settings']:
                game_type = c['settings']['gamename_key']

            gamename = gamename + ' - ' + game_type

            points, _, total = c['score'].partition('/')
            activity, _ = Activity.objects.get_or_create(name=gamename)
            new_grade = UserGrade.objects.create(user=request.user.get_profile(),
                                                game=activity,
                                                score=points,
                                                total=total)

@login_required
def courses_coursegoal_sub_goal_add(request):
    template = 'course_goal_constructor_iframe.html'
    c = {'dialog': True}
    return render_to_response(request, template, c)

@login_required
def courses_goal_construction(request):
    template = 'courses_main_goals.html'
    c = {'coursegoal': False,
         'for_iframe': False
        }
    return render_to_response(request, template, c)

@login_required
def courses_coursegoal_construction(request):
    template = 'courses_main_goals.html'
    c = {'coursegoal': True,
         'for_iframe': False
        }
    return render_to_response(request, template, c)

@login_required
def courses_stats(request):
    """ This is the main view presented to users after login.
        Instructors will be shown a link to view grades and student progress,
        students will be shown their current progress in all of the games
        that they have records in.
    """

    template = 'courses_stats.html'

    c = {}
    new_profile = None
    is_student = None

    try:
        profile = request.user.get_profile()
        new_profile = False
    except UserProfile.DoesNotExist:
        profile = UserProfile.objects.create(user=request.user)
        profile.save()
        new_profile = True

    summary = False

    if profile.is_instructor:
        if request.GET.get('student_view', False):
            is_student = True
        else:
            is_student = False
    else:
        is_student = True

    if is_student:
        summary = profile.usergradesummary_set.all()
        if summary.count() == 0:
            new_profile = True

    user_defined_goals = Goal.objects.filter(created_by=request.user, course=None)

    c = {
        'user':  request.user,
        'profile':  profile,
        'new_profile':  new_profile,
        'is_student':  is_student,
        'summaries':  summary,
        'courses': profile.studentships,
        'user_defined_goals': user_defined_goals
    }
    return render_to_response(request, template, c)

@login_required
def personal_goals(request):
    """ This is the main view presented to users after login.
        Instructors will be shown a link to view grades and student progress,
        students will be shown their current progress in all of the games
        that they have records in.
    """

    template = 'personal_goals.html'

    c = {}
    new_profile = None
    is_student = None

    try:
        profile = request.user.get_profile()
        new_profile = False
    except UserProfile.DoesNotExist:
        profile = UserProfile.objects.create(user=request.user)
        profile.save()
        new_profile = True

    summary = False

    user_defined_goals = Goal.objects.filter(created_by=request.user, course=None)

    c = {
        'user':  request.user,
        'profile':  profile,
        'new_profile':  new_profile,
        'is_student':  is_student,
        'user_defined_goals': user_defined_goals
    }
    return render_to_response(request, template, c)


@login_required
def courses_main(request):
    """ This is the main view presented to users after login.
        Instructors will be shown a link to view grades and student progress,
        students will be shown their current progress in all of the games
        that they have records in.
    """

    if 'survey_done' in request.GET:
        request.session['no_surveys'] = True

    if request.user.get_profile().login_count < 2:
        if 'no_surveys' not in request.session:
            request.session['courses_survey_redirect'] = True
            redir = '/%s/survey/answer/' % URL_PREFIX
            return HttpResponseRedirect(redir)

    template = 'courses_main.html'

    c = {}
    new_profile = None
    is_student = None

    try:
        profile = request.user.get_profile()
        new_profile = False
    except UserProfile.DoesNotExist:
        profile = UserProfile.objects.create(user=request.user)
        profile.save()
        new_profile = True

    summary = False

    if profile.is_instructor:
        if request.GET.get('student_view', False):
            template = 'courses_main.html'
            is_student = True
        else:
            template = 'courses_main_instructor.html'
            is_student = False
    else:
        template = 'courses_main.html'
        is_student = True

    if is_student:
        summary = profile.usergradesummary_set.all()
        if summary.count() == 0:
            new_profile = True

    user_defined_goals = Goal.objects.filter(created_by=request.user, course=None)

    c = {
        'user':  request.user,
        'profile':  profile,
        'new_profile':  new_profile,
        'is_student':  is_student,
        'summaries':  summary,
        'courses': profile.studentships,
        'user_defined_goals': user_defined_goals
    }
    return render_to_response(request, template, c)

from django.contrib.auth.decorators import user_passes_test

def instructor_group(user):
    if user.get_profile().is_instructor:
        return True
    else:
        return False

def instructor_can_see_student(instructor, student):
    # Instructor's course IDs
    instructor_p = instructor.get_profile()
    instructor_courses = list([a.id for a in instructor_p.instructorships])

    # Student's ...
    student_p = student.get_profile()
    student_courses = list([a.id for a in student_p.courses])
    intersection = list(set(instructor_courses) & set(student_courses))

    if len(intersection) == 0:
        return False
    else:
        return True

@user_passes_test(instructor_group)
def instructor_student_detail(request, uid, cid):
    student = UserProfile.objects.get(user__id=uid)
    instructor = request.user.get_profile()

    instructor_courses = list([a.id for a in instructor.instructorships])
    course_for_inst = [a for a in instructor_courses if a == long(cid)]

    if len(course_for_inst) > 0:
        course = course_for_inst[0]
        course = Course.objects.get(id=course)
    else:
        course = False

    student_courses = list([a.id for a in student.courses])

    intersection = list(set(instructor_courses) & set(student_courses))

    if len(intersection) == 0 or not course:
        error = 'Student not found.'
        return HttpResponseForbidden(error)

    template = 'instructor_student_detail.html'
    c = {}
    c['student'] = UserProfile.objects.get(user__id=uid)
    c['course'] = course
    return render_to_response(request, template, c)

def goal_history(request, goal_id, user_id=None):
    from django.contrib.auth.models import User
    from .models import UserActivityLog
    from .models import incorrects_by_frequency

    if user_id is None:
        u = request.user
    else:
        requested_user = User.objects.get(id=user_id)
        if request.user.id == user_id:
            u = request.user
        else:
            # Likely an instructor is requesting this user_id, so we
            # need to make sure they have access
            if instructor_can_see_student(request.user, requested_user):
                u = requested_user
            else:
                u = request.user

    goal = Goal.objects.get(id=goal_id)
    instances = UserGoalInstance.objects.filter(user=u, goal=goal_id)\
                                        .order_by('-last_attempt')
    instances_rev = UserGoalInstance.objects.filter(user=u, goal=goal_id)\
                                        .order_by('last_attempt')
    template = 'goal_history.html'
    c = {}
    c['student'] = u.get_profile()
    c['goal'] = goal
    c['goal_instances'] = instances
    c['incorrects'] = incorrects_by_frequency(u, goal=goal)
    c['spark_data'] = ','.join(map(str, instances_rev.values_list('correct', flat=True)))
    return render_to_response(request, template, c)

def begin_course_task(request, task_id):
    """ Mark the session with the goal ID, and redirect the user to the
    goal's start page.
    """
    from .models import Goal, UserActivityLog

    task_id = int(task_id)

    # Reset any session variables for tracking progress
    if 'all_correct' in request.session:
        del request.session['all_correct']
    if 'set_completed' in request.session:
        del request.session['set_completed']
    if 'new_game' in request.session:
        del request.session['new_game']
    if 'prev_new_game' in request.session:
        del request.session['prev_new_game']

    request.session['question_set_count'] = 0
    request.session['question_try_count'] = {}
    request.session['answered'] = {}

    try: del request.session['previous_exercise_params']
    except: pass

    try: del request.session['current_exercise_params']
    except: pass

    try: del request.session['current_user_goal']
    except: pass

    try: del request.session['max_rounds']
    except: pass

    try: del request.session['correct_threshold']
    except: pass

    request.session['prev_new_game'] = False

    # Check that the user has the goal
    user_courses = request.user.get_profile().courses
    user_own_goals = list(Goal.objects.filter(created_by=request.user,
                                              course=None))

    user_course_goals = [coursegoalgoal.goal for course in user_courses
                              for coursegoal in course.coursegoal_set.all()
                              for coursegoalgoal in coursegoal.goals.all()
                        ] + user_own_goals

    goal_ids = list(set([int(g.id) for g in user_course_goals]))

    if not task_id in goal_ids:
        return HttpResponseForbidden("This is missing, or you do not have access.")

    # TODO: redirect to beginning of course goal

    goal = Goal.objects.get(id=task_id)

    # Reset goal progress
    # TODO: will this need to be connected to a usergoalinstance?
    # UserActivityLog.objects.filter(user=request.user, goal=goal)

    UserGoalInstance.objects.filter(user=request.user, goal=goal).update(opened=False)
    ugi = UserGoalInstance.objects.create(user=request.user, goal=goal)
    request.session['current_user_goal'] = int(ugi.id)
    request.session['max_rounds'] = goal.minimum_sets_attempted
    request.session['correct_threshold'] = goal.threshold

    return HttpResponseRedirect(goal.start_url())


@user_passes_test(instructor_group)
def course_invite(request, c_id=None):

    if c_id:
        c_id = int(c_id)

    def by_id(course):
        if c_id == None:
            return True
        return course.id == c_id

    c = {}
    profile = request.user.get_profile()
    c['profile'] = profile
    c['course_invites'] = filter(by_id, profile.instructorships)
    template = 'invite_students.html'
    return render_to_response(request, template, c)

@user_passes_test(instructor_group)
def reset_invite_link(request, cid):
    template = 'reset_invite_link.html'
    c = {}

    instructor = request.user.get_profile()
    instructor_courses = list([int(a.id) for a in instructor.instructorships])
    if not request.user.is_superuser:
        if cid not in instructor_courses:
            error = 'This is not your course.'
            return HttpResponseForbidden(error)

    course = Course.objects.get(id=cid)

    if request.method == 'GET':
        c['confirmation'] = True
    elif request.method == 'POST':
        course.token = course.generate_new_key()
        course.save()
        c['confirmation'] = False
        c['reset_success'] = True
        c['course'] = course

        new_link = 'TODO'
        c['new_link'] = new_link
	return render_to_response(request, template, c)

def course_enroll(request):
    from django.core.urlresolvers import reverse

    # invite stored in 'key' parameter.
    # "http://"+hst+"/davvi/courses/enroll/?key=NDg.BioJAg.E2-Y6uBwr6_35Qhk03uBamTTnHc"


    # TODO: if user isn't logged in, store the invite key in the session
    # before redirecting them to log in (we assume they already have a
    # user account because of cookie auth).

    # TODO: when user lands on this page, pop the stored key if it
    # exists, and key isn't set.

    # TODO: enroll user in course

    # TODO: notify instructors of enrollment changes (post-save signal
    # instead?)
    enrollment_key = request.GET.get('key', False)
    session_key = False

    if request.user.is_anonymous():
        request.session['enrollment_key'] = enrollment_key
        next_page = '/%s/courses/enroll/' % URL_PREFIX
        return HttpResponseRedirect(reverse('courses_login') + '?next=' + next_page)

    if not enrollment_key:
        try:
            enrollment_key = request.session.get('enrollment_key')
            session_key = True
        except:
            pass

    if enrollment_key:
        course = Course.objects.get(token=enrollment_key)
    else:
        course = False

    enrolled = False

    # notify these when the enrollment works
    enrolled, error = course.add_student(request.user)

    c = {
        'enrollment_key': enrollment_key,
        'session_key': session_key,
        'target_course': course,
        'incoming_user': request.user,
    }

    if enrolled:
        try:
            enrollment_key = request.session.get('enrollment_key')
            session_key = True
        except:
            pass
    else:
        c['error'] = error

	return render_to_response(request, 'course_enroll.html', c)

@login_required
def recipient_search(request):
    # https://github.com/philippWassibauer/django-threaded-messages
    from django.contrib.auth.models import User
    from django.db.models import Q

    from django.core.urlresolvers import reverse
    from django.http import HttpResponse
    import simplejson

    # TODO: filter by user's fellow students/instructors/etc.
    term = request.GET.get("term")
    users = User.objects.filter(Q(first_name__icontains=term)|
                                Q(last_name__icontains=term)|
                                Q(username__icontains=term)|
                                Q(email__icontains=term))
    if request.GET.get("format") == "json":
        data = []
        for user in users:
            # avatar_img_url = avatar_url(user, size=50)
            data.append({"id": user.username,
                         "name": "%s" % str(user),
                        })

        return HttpResponse(simplejson.dumps(data),
                            mimetype='application/json')
