# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

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