from django.conf import settings
from django.contrib.auth.models import User
from membersuite_api_client.client import ConciergeClient
from membersuite_api_client.security.services import (
    LoginToPortalError,
    get_user_for_membersuite_entity)

from .models import MemberSuitePortalUser
from .services import MemberSuitePortalUserService


class MemberSuiteBackend(object):

    def __init__(self, client=None, user_service=None, *args, **kwargs):
        self.client = client or ConciergeClient(
            access_key=settings.MS_ACCESS_KEY,
            secret_key=settings.MS_SECRET_KEY,
            association_id=settings.MS_ASSOCIATION_ID)
        self.user_service = MemberSuitePortalUserService(client=self.client)

    def authenticate(self, username=None, password=None):
        """Returns the appropriate django.contrib.auth.models.User if
        successful; otherwise returns None.

        If login succeeds and there's no MemberSuitePortalUser that
        matches on membersuite_id;

            1) one is created, and;

            2) a User object might be created too.

        Plus, the is_member attribute on MemberSuitePortalUser is set
        when login succeeds.

        Plus, when a MemberSuitePortalUser is created, the related
        User object gets its names and email updated from MemberSuite.

        Finally, "MAINTENANCE_MODE" is supported, during which all but
        staff logins will fail.

        """
        try:
            authenticated_portal_user = self.user_service.login(
                username=username,
                password=password)
        except LoginToPortalError:
            return None

        try:
            membersuite_portal_user = MemberSuitePortalUser.objects.get(
                membersuite_id=authenticated_portal_user.membersuite_id)

        except MemberSuitePortalUser.DoesNotExist:

            if getattr(settings, "MAINTENANCE_MODE", False):
                return None

            user, user_created = get_user_for_membersuite_entity(
                membersuite_entity=authenticated_portal_user)

            is_member = self.is_member(
                membersuite_portal_user=authenticated_portal_user)

            membersuite_portal_user = MemberSuitePortalUser.objects.create(
                user=user,
                membersuite_id=authenticated_portal_user.membersuite_id,
                is_member=is_member)

            if not user_created:
                # Update User attributes in case they changed
                # in MemberSuite.
                user.email = authenticated_portal_user.email_address
                user.first_name = authenticated_portal_user.first_name
                user.last_name = authenticated_portal_user.last_name

            user.set_unusable_password()  # Do we really want to do this?

            user.save()

        else:
            # Found a MemberSuitePortalUser. Update cached info.
            membersuite_portal_user.is_member = self.is_member(
                membersuite_portal_user=authenticated_portal_user)
            membersuite_portal_user.save()

        if (getattr(settings, "MAINTENANCE_MODE", None) and
            not membersuite_portal_user.user.is_staff):  # noqa

            return None

        return membersuite_portal_user.user

    def get_user(self, user_id):
        try:
            return User.objects.get(pk=user_id)
        except User.DoesNotExist:
            return None

    def is_member(self, membersuite_portal_user, client=None):
        client = client or self.client

        individual = membersuite_portal_user.get_individual(client=client)
        is_member = individual.is_member(client=client)

        return is_member

@@ -998,16 +998,24 @@
 suite_id
+ or user
 ;%0A%0A     
@@ -1653,32 +1653,67 @@
    return None%0A%0A
+        # Match on membersuite ID?%0A
         try:%0A   
@@ -2119,32 +2119,247 @@
 d_portal_user)%0A%0A
+            # Match on user?%0A            try:%0A                membersuite_portal_user = MemberSuitePortalUser.objects.get(%0A                    user=user)%0A%0A            except MemberSuitePortalUser.DoesNotExist:%0A%0A    
             is_m
@@ -2390,32 +2390,36 @@
                 
+   
+ 
 membersuite_port
@@ -2446,32 +2446,36 @@
 d_portal_user)%0A%0A
+    
             memb
@@ -2542,32 +2542,36 @@
                 
+   
+ 
 user=user,%0A     
@@ -2565,16 +2565,20 @@
 r=user,%0A
+    
         
@@ -2650,32 +2650,36 @@
                 
+   
+ 
 is_member=is_mem
@@ -2696,16 +2696,20 @@
         
+    
 if not u
@@ -2721,16 +2721,20 @@
 reated:%0A
+    
         
@@ -2803,16 +2803,20 @@
         
+    
 # in Mem
@@ -2825,16 +2825,20 @@
 rSuite.%0A
+    
         
@@ -2910,24 +2910,28 @@
             
+    
 user.first_n
@@ -2973,16 +2973,20 @@
 st_name%0A
+    
         
@@ -3055,24 +3055,28 @@
             
+    
 user.set_unu
@@ -3126,16 +3126,20 @@
  this?%0A%0A
+    
         

Add match on User to methods used to find MemberSuitePortalUser.