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.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

from app_mgr.permissions import ViewControlObjectPermissions
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

class OrganizationListView(generics.ListCreateAPIView):
    """
    Returns a list of all organizations.
    """
    queryset = Organization.objects.all()
    serializer_class = OrganizationSerializer

class ApplicationListView(generics.ListCreateAPIView):
    """
    Returns a list of all applications.
    """
    queryset = Application.objects.all()
    serializer_class = ApplicationSerializer

# 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.
    """
    queryset = Organization.objects.all()
    serializer_class = OrganizationSerializer

class ApplicationInstanceView(generics.RetrieveUpdateDestroyAPIView):
    """
    Returns a single app.
    """
    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,
                  }
                 )
