from django.shortcuts import render, redirect, render_to_response
from django.http import HttpResponseRedirect, HttpResponse
from django.contrib.auth.decorators import login_required
from django.contrib.auth import authenticate, login, logout, get_user_model
from django.contrib.auth.views import password_reset, password_reset_confirm
from django.contrib.sites.shortcuts import get_current_site
from django.core.urlresolvers import reverse
from django.template import RequestContext
from django.conf import settings

from django.db import IntegrityError
from django.db.models import Q

from django.views.generic.base import RedirectView

from axes.decorators import watch_login

from rest_framework import generics
from rest_framework.authentication import TokenAuthentication
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response

from guardian.shortcuts import assign_perm, get_objects_for_user

from app_mgr.permissions import ViewControlObjectPermissions
from app_mgr.permissions import ApplicationObjectPermissions
from app_mgr.models import UserProfile, Organization, Application, AppVersion
from app_mgr.serializers import UserProfileSerializer, OrganizationSerializer, ApplicationSerializer

import datetime

#
# RESTFUL VIEWS
#

# LIST RETRIEVE
class UserProfileListView(generics.ListCreateAPIView):
    """
    Returns a list of all user profiles.
    """
    authentication_classes = (TokenAuthentication,)
    permission_classes = (IsAuthenticated,)

    queryset = UserProfile.objects.all()
    serializer_class = UserProfileSerializer

    def get_queryset(self):
        # only used for list
        return get_objects_for_user(self.request.user, "view_userprofile", 
                                    UserProfile.objects.all())

class OrganizationListView(generics.ListCreateAPIView):
    """
    Returns a list of all organizations.
    """
    authentication_classes = (TokenAuthentication,)
    permission_classes = (IsAuthenticated,)

    queryset = Organization.objects.all()
    serializer_class = OrganizationSerializer

    def get_queryset(self):
        # only used for list
        return get_objects_for_user(self.request.user, "view_organization", 
                                    Organization.objects.all())

class ApplicationListView(generics.ListCreateAPIView):
    """
    Returns a list of all applications.
    """
    authentication_classes = (TokenAuthentication,)
    permission_classes = (IsAuthenticated,)

    queryset = Application.objects.all()
    serializer_class = ApplicationSerializer

    def get_queryset(self):
        # only used for list
        owned = get_objects_for_user(self.request.user, "view_application", 
                                     Application.objects.all())
        public = Application.objects.filter(isPublic=True)

        viewable = list(set(list(owned) + list(public)))
       
        return viewable

# SINGLE RETRIEVE/UPDATE/DESTROY
class UserProfileInstanceView(generics.RetrieveUpdateDestroyAPIView):
    """
    Returns a single user.
    """
    authentication_classes = (TokenAuthentication,)
    permission_classes = (ViewControlObjectPermissions,)
    _ignore_model_permissions = True

    queryset = UserProfile.objects.all()
    serializer_class = UserProfileSerializer

    def get(self, request, *args, **kwargs):
        if kwargs['pk'] == 'current':
            self.kwargs['pk'] = str(request.user.id)
        return self.retrieve(request, *args, **kwargs)

    def put(self, request, *args, **kwargs):
        if kwargs['pk'] == 'current':
            self.kwargs['pk'] = str(request.user.id)
        return self.update(request, *args, **kwargs)

    def patch(self, request, *args, **kwargs):
        if kwargs['pk'] == 'current':
            self.kwargs['pk'] = str(request.user.id)
        return self.partial_update(request, *args, **kwargs)

    def delete(self, request, *args, **kwargs):
        if kwargs['pk'] == 'current':
            self.kwargs['pk'] = str(request.user.id)
        return self.destroy(request, *args, **kwargs)

class OrganizationInstanceView(generics.RetrieveUpdateDestroyAPIView):
    """
    Returns a single org.
    """
    authentication_classes = (TokenAuthentication,)
    permission_classes = (ViewControlObjectPermissions,)
    _ignore_model_permissions = True

    queryset = Organization.objects.all()
    serializer_class = OrganizationSerializer

class ApplicationInstanceView(generics.RetrieveUpdateDestroyAPIView):
    """
    Returns a single app.
    """
    authentication_classes = (TokenAuthentication,)
    permission_classes = (ApplicationObjectPermissions,)
    _ignore_model_permissions = True

    queryset = Application.objects.all()
    serializer_class = ApplicationSerializer

# REDIRECTS
#class UserRedirectView(RedirectView):
#
#    permanent = False
#    query_string = True
#    #pattern_name = 'user-instance'
#
#    def get(self, request, *args, **kwargs):
#        print request
#        print request.user.id
#        print request.auth
#        kwargs['pk'] = request.user.id
#        self.url = '/app_mgr/user/%s' % (request.user.id)
#        return super(UserRedirectView, self).get(request, args, **kwargs)

#
# AUTHENTICATION VIEWS
#

# creates a new user 
def register(request):
    # TODO : add logging back in.  Good practice!!
    # Like before, get the request's context.
    context = RequestContext(request)

    # A boolean value for telling the template whether the registration was successful.
    # Set to False initially. Code changes value to True when registration succeeds.
    registrationSuccessful = False
    userExists = False
    error = False

    # If it's a HTTP POST, we're interested in processing form data.
    if request.method == 'POST':

        # Now we hash the password with the set_password method.
        # Once hashed, we can update the user object.
        user = get_user_model()(email=request.POST['email'])
        user.set_password(request.POST['password'])
        user.last_login = '1970-01-01 00:00'

        if not user.email or not request.POST['password']:
            error = True
            return render_to_response('registration/register.html', {'registrationSuccessful': registrationSuccessful, 'userExists': userExists, 'error': error}, context)

        try:
            user.save()
        except IntegrityError:
            userExists = True
            return render_to_response('registration/register.html', {'registrationSuccessful': registrationSuccessful, 'userExists': userExists, 'error': error}, context)

        # Now sort out the UserProfile instance.
        # Since we need to set the user attribute ourselves, we set commit=False.
        # This delays saving the model until we're ready to avoid integrity problems.
        ###userprofile = UserProfile()
        ###userprofile.user = user

        # Now we save the UserProfile model instance.
        ###userprofile.save()

        # Set permissions for own profile
        assign_perm('view_userprofile', user, user)
        assign_perm('change_userprofile', user, user)
        assign_perm('delete_userprofile', user, user)
        #assign_perm('view_userprofile', user, userprofile)
        #assign_perm('change_userprofile', user, userprofile)
        #assign_perm('delete_userprofile', user, userprofile)

        # Update our variable to tell the template registration was successful.
        registrationSuccessful = True

        # add some logic to log events, log in users directly
        #print "successful registration of " + request.POST['email'] +" "+ datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        print( "successful registration of {0} {1}".format(request.POST['email'], datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")) )
        request.POST['email_to'] = user.email
        request.POST['email_subject'] = 'Welcome to TAP'
        request.POST['email_message'] = 'Your registration was successful!\n\nIn case you forget your password, please go to the following page and reset your password:\n\nhttps://' + get_current_site(request).domain + '/app_mgr/reset/\n\nYour username, in case you\'ve forgotten, is the email address this message was sent to.\n\nThanks for using our site!\n\nThe ' + get_current_site(request).name + ' team'

        # Update this if TAP wants email on registration
        #exp_portal.email.send_email(request)

    #return render_to_response('abcd.html', context)
    return render_to_response('registration/register.html', {'registrationSuccessful': registrationSuccessful, 'userExists': userExists, 'error': error}, context)


def logout_user(request):
    """
    Log users out and re-direct them to the main page.
    """
    logout(request)
    return HttpResponseRedirect('/app_mgr/login')

@watch_login
def login_user(request):
        # Like before, obtain the context for the user's request.
    context = RequestContext(request)

    # If the request is a HTTP POST, try to pull out the relevant information.
    if request.method == 'POST':
        # Gather the username (email) and password provided by the user.
        # This information is obtained from the login form.
        email = request.POST['email']
        password = request.POST['password']
        # print "Login attempt by " + username + " at " + datetime

        # Use Django's machinery to attempt to see if the username/password
        # combination is valid - a User object is returned if it is.
        user = authenticate(email=email, password=password)

        # If we have a User object, the details are correct.
        # If None (Python's way of representing the absence of a value), no user
        # with matching credentials was found.
        if user:
            # Is the account active? It could have been disabled.
            if user.is_active:
                # If the account is valid and active, we can log the user in.
                # We'll send the user back to the homepage.
                login(request, user)
                return HttpResponseRedirect('/app_mgr/user_profile')
            else:
                # An inactive account was used - no logging in!
                return HttpResponse("Your TAP account is disabled.")
        else:
            # Bad login details were provided. So we can't log the user in.
            print( "Invalid login details: {0}, {1}".format(email, password) )
            return HttpResponse("Invalid login details supplied.")

    # The request is not a HTTP POST, so display the login form.
    # This scenario would most likely be a HTTP GET.
    else:
        # No context variables to pass to the template system, hence the
        # blank dictionary object...
        # experiment_title = title
        return render(request, 'registration/login.html')
        # return render(request, 'registration/login.html', {'experiment_title': experiment_title})

        # return login_view(request, authentication_form=MyAuthForm)

def reset_confirm(request, uidb64=None, token=None):
    return password_reset_confirm(request, template_name='registration/reset_password_confirm.html',
                                  uidb64=uidb64, token=token,
                                  post_reset_redirect=reverse('app_mgr:login'))


def reset(request):
    return password_reset(request, template_name='registration/reset_password_form.html',
                          email_template_name='registration/reset_password_email.html',
                          post_reset_redirect=reverse('app_mgr:reset_sent'),
                          from_email=settings.EMAIL_FROM_NOMINAL_ADDRESS)

def reset_sent(request):
    return render(request, 'registration/reset_password_done.html')

@login_required(login_url='/app_mgr/login')
def view_profile(request):
    user = request.user
    return render(request, 'user_profile.html',
                  {'user': request.user,
                  }
                 )
