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

from ldap3 import Connection

from django import shortcuts
from django.http import Http404
from django.db.models import Q
from django.contrib.auth.models import User
from django.conf import settings

from gestioncof.models import CofProfile
from gestioncof.decorators import buro_required


class Clipper(object):
    def __init__(self, clipper, fullname):
        if fullname is None:
            fullname = ""
        assert isinstance(clipper, str)
        assert isinstance(fullname, str)
        self.clipper = clipper
        self.fullname = fullname


@buro_required
def autocomplete(request):
    if "q" not in request.GET:
        raise Http404
    q = request.GET['q']
    data = {
        'q': q,
    }

    queries = {}
    bits = q.split()

    # Fetching data from User and CofProfile tables
    queries['members'] = CofProfile.objects.filter(is_cof=True)
    queries['users'] = User.objects.filter(profile__is_cof=False)
    for bit in bits:
        queries['members'] = queries['members'].filter(
            Q(user__first_name__icontains=bit)
            | Q(user__last_name__icontains=bit)
            | Q(user__username__icontains=bit)
            | Q(login_clipper__icontains=bit))
        queries['users'] = queries['users'].filter(
            Q(first_name__icontains=bit)
            | Q(last_name__icontains=bit)
            | Q(username__icontains=bit))
    queries['members'] = queries['members'].distinct()
    queries['users'] = queries['users'].distinct()

    # Clearing redundancies
    usernames = (
        set(queries['members'].values_list('login_clipper', flat='True'))
        | set(queries['users'].values_list('profile__login_clipper',
                                           flat='True'))
    )

    # Fetching data from the SPI
    if hasattr(settings, 'LDAP_SERVER_URL'):
        # Fetching
        ldap_query = '(&{:s})'.format(''.join(
            '(|(cn=*{bit:s}*)(uid=*{bit:s}*))'.format(bit=bit)
            for bit in bits if bit.isalnum()
        ))
        if ldap_query != "(&)":
            # If none of the bits were legal, we do not perform the query
            entries = None
            with Connection(settings.LDAP_SERVER_URL) as conn:
                conn.search(
                    'dc=spi,dc=ens,dc=fr', ldap_query,
                    attributes=['uid', 'cn']
                )
                entries = conn.entries
            # Clearing redundancies
            queries['clippers'] = [
                Clipper(entry.uid.value, entry.cn.value)
                for entry in entries
                if entry.uid.value
                and entry.uid.value not in usernames
            ]

    # Resulting data
    data.update(queries)
    data['options'] = sum(len(query) for query in queries)

    return shortcuts.render(request, "autocomplete_user.html", data)