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 rest_framework.authtoken import views as token_views

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
import requests 

#
# 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)
                userToken = get_token(email, password)
                print( "Successful Login: {0}, id: {1}, token: {2}".format(email, user.id, userToken) )
                return HttpResponse(userToken)
            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) ) ###TODO - PASSWORD EXPOSED
            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 get_token(email, password):
    credentials = {'username':email, 'password':password}
    tokenResponse = requests.post('http://localhost:8000/api-token-auth/', credentials)
    return tokenResponse.text

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,
                  }
                 )

# def get_app_results_fields(request, check):
#     user = request.user
#     return render(request, 'user_profile.html',
#                   {'user': request.user,
#                   }
#                  )

# def get_app_results(request, check):
#     user = request.user
#     return render(request, 'user_profile.html',
#                   {'user': request.user,
#                   }
#                  )

def app_results(request, appId, searchType):
    print ("hello")
    print (appId)
    print (searchType)
    return render(request, 'user_profile.html',
                  {'user': request.user,
                  }
                 )

def app_results_byname(request, appName, searchType):
    print ("hello")
    print (appName)
    print (searchType)
    return render(request, 'user_profile.html',
                  {'user': request.user,
                  }
                 )