from django.conf import settings
from django.contrib.auth import get_user_model
from django.utils.six.moves import urllib_parse
from django.utils.six.moves.urllib_request import urlopen, Request
from django_cas_ng.cas import CASClientV2
import logging


logger = logging.getLogger(__name__)


class CASClientRemie(CASClientV2):

    def verify_ticket(self, ticket):
        """Verifies CAS 2.0+ XML-based authentication ticket."""
        try:
            from xml.etree import ElementTree
        except ImportError:
            from elementtree import ElementTree

        user = None
        pgtiou = None

        params = [('ticket', ticket), ('service', self.service_url)]
        if self.proxy_callback:
            params.append(('pgtUrl', self.proxy_callback))

        url = (urllib_parse.urljoin(self.server_url, 'serviceValidate') + '?' +
               urllib_parse.urlencode(params))
        page = urlopen(url)
        try:
            response = page.read()
            logger.debug("Verify CAS response : ")
            logger.debug(response)
            tree = ElementTree.fromstring(response)
            if tree[0].tag.endswith('authenticationSuccess'):
                attributes = {}
                for element in tree[0]:
                    if element.tag.endswith('user'):
                        user = element.text
                    elif element.tag.endswith(':nom'):
                        attributes['last_name'] = element.text
                    elif element.tag.endswith(':prenom'):
                        attributes['first_name'] = element.text
                    elif element.tag.endswith('proxyGrantingTicket'):
                        pgtiou = element.text
                return user, attributes, pgtiou
            else:
                return None, None, None
        finally:
            page.close()

    def get_or_create_user(self, username, attributes):
        """get or create a user
        Return (created, user).
        The returned user can be `None`.
        """
        if not username:
            return None, False

        User = get_user_model()

        if attributes is None:
            attributes = {}

        try:
            user = User.objects.get(**{User.USERNAME_FIELD: username})
            created = False
        except User.DoesNotExist:
            # check if we want to create new users, if we don't fail auth
            create = getattr(settings, 'CAS_CREATE_USER', True)
            if not create:
                return None, False
            # user will have an "unusable" password
            user = User.objects.create_user(username=username, password='', first_name=attributes.get('first_name',''), last_name=attributes.get('last_name', ''))
            user.save()
            created = True
        return created, user
