# -*- coding: utf-8 -*-

from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals

from django.contrib.sites.models import Site
from django.conf import settings
from django_cas_ng.backends import CASBackend
from django_cas_ng.utils import get_cas_client
from django.contrib.auth import get_user_model
from django.contrib.auth.models import User as DjangoUser
from django.db import connection
from django.core.mail import send_mail
from django.template import Template, Context

from gestioncof.models import CofProfile, CustomMail

User = get_user_model()


class COFCASBackend(CASBackend):
    def authenticate_cas(self, ticket, service, request):
        """Verifies CAS ticket and gets or creates User object"""

        client = get_cas_client(service_url=service)
        username, attributes, _ = client.verify_ticket(ticket)
        if attributes:
            request.session['attributes'] = attributes
        if not username:
            return None

        # Le CAS de l'ENS accepte les logins avec des espaces au début
        # et à la fin, ainsi qu’avec une casse variable. On normalise pour
        # éviter les doublons.
        username = username.strip().lower()

        profiles = CofProfile.objects.filter(login_clipper=username)
        if len(profiles) > 0:
            profile = profiles.order_by('-is_cof')[0]
            user = profile.user
            return user
        try:
            user = User.objects.get(username=username)
        except User.DoesNotExist:
            # user will have an "unusable" password
            user = User.objects.create_user(username, '')
            user.save()
        return user

    def authenticate(self, ticket, service, request):
        """Authenticates CAS ticket and retrieves user data"""
        user = self.authenticate_cas(ticket, service, request)
        if user is None:
            return user
        try:
            profile = user.profile
        except CofProfile.DoesNotExist:
            profile, created = CofProfile.objects.get_or_create(user=user)
            profile.save()
        if not profile.login_clipper:
            profile.login_clipper = user.username
            profile.save()
        if not user.email:
            user.email = settings.CAS_EMAIL_FORMAT % profile.login_clipper
            user.save()
        if profile.is_buro and not user.is_staff:
            user.is_staff = True
            user.save()
        return user


def context_processor(request):
    '''Append extra data to the context of the given request'''
    data = {
            "user": request.user,
            "site": Site.objects.get_current(),
           }
    return data


def lock_table(*models):
    query = "LOCK TABLES "
    for i, model in enumerate(models):
        table = model._meta.db_table
        if i > 0:
            query += ", "
        query += "%s WRITE" % table
    cursor = connection.cursor()
    cursor.execute(query)
    row = cursor.fetchone()
    return row


def unlock_tables(*models):
    cursor = connection.cursor()
    cursor.execute("UNLOCK TABLES")
    row = cursor.fetchone()
    return row

unlock_table = unlock_tables


def send_custom_mail(to, shortname, context=None, from_email="cof@ens.fr"):
    if context is None:
        context = {}
    if isinstance(to, DjangoUser):
        context["nom"] = to.get_full_name()
        context["prenom"] = to.first_name
        to = to.email
    mail = CustomMail.objects.get(shortname=shortname)
    template = Template(mail.content)
    message = template.render(Context(context))
    send_mail(mail.title, message,
              from_email, [to],
              fail_silently=True)