import os
import base64
import hashlib
from collections import defaultdict
from django.db.models import F, Q
from planetstack.config import Config
from observer.openstacksyncstep import OpenStackSyncStep
from core.models.site import SiteDeployments, Deployment
from core.models.user import User, UserDeployments
from util.logger import Logger, logging

logger = Logger(level=logging.INFO)

class SyncUserDeployments(OpenStackSyncStep):
    provides=[User, UserDeployments]
    requested_interval=0

    def fetch_pending(self):
        # user deployments are not visible to users. We must ensure
        # user are deployed at all deploymets available to their sites.

        deployments = Deployment.objects.all()
        site_deployments = SiteDeployments.objects.all()
        site_deploy_lookup = defaultdict(list)
        for site_deployment in site_deployments:
            site_deploy_lookup[site_deployment.site].append(site_deployment.deployment)
        
        user_deployments = []                
        for user in User.objects.filter(Q(enacted__lt=F('updated')) | Q(enacted=None)):
            if user.is_admin:
                # admins should have an account at all deployments
                expected_deployments = deployments
            else:
                # normal users should have an account at their site's deployments
                expected_deployments = site_deploy_lookup[user.site]
            for expected_deployment in expected_deployments:
                ud = UserDeployments(user=user, deployment=expected_deployment)
                user_deployments.append(ud)

        return user_deployments

    def sync_record(self, user_deployment):
        logger.info("sync'ing user %s at deployment %s" % (user_deployment.user, user_deployment.deployment.name))
        name = user_deployment.user.email[:user_deployment.user.email.find('@')]
        user_fields = {'name': user_deployment.user.email,
                       'email': user_deployment.user.email,
                       'password': hashlib.md5(user_deployment.user.password).hexdigest()[:6],
                       'enabled': True}    
        driver = self.driver.admin_driver(deployment=user_deployment.deployment.name)
        if not user_deployment.kuser_id:
            keystone_user = driver.create_user(**user_fields)
            user_deployment.kuser_id = keystone_user.id
        else:
            driver.update_user(user_deployment.kuser_id, user_fields)

        # setup user deployment home site roles  
        if user_deployment.user.site:
            site_deployments = SiteDeployments.objects.filter(site=user_deployment.user.site,
                                                              deployment=user_deployment.deployment)
            if site_deployments:
                # need the correct tenant id for site at the deployment
                tenant_id = site_deployments[0].tenant_id  
                driver.add_user_role(user_deployment.kuser_id, 
                                     tenant_id, 'user')
                if user_deployment.user.is_admin:
                    driver.add_user_role(user_deployment.kuser_id, tenant_id, 'admin')
                else:
                    # may have admin role so attempt to remove it
                    driver.delete_user_role(user_deployment.kuser_id, tenant_id, 'admin')

        #if user_deployment.user.public_key:
        #    if not user_deployment.user.keyname:
        #        keyname = user_deployment.user.email.lower().replace('@', 'AT').replace('.', '')
        #        user_deployment.user.keyname = keyname
        #        user_deployment.user.save()
        #    
        #    user_driver = driver.client_driver(caller=user_deployment.user, 
        #                                       tenant=user_deployment.user.site.login_base, 
        #                                       deployment=user_deployment.deployment.name)
        #    key_fields =  {'name': user_deployment.user.keyname,
        #                   'public_key': user_deployment.user.public_key}
        #    user_driver.create_keypair(**key_fields)

        user_deployment.save()
