import logging
import random
import string
import requests

import owncloud as NextCloudCLI


from django.dispatch import receiver
from django.db.models.signals import post_save, post_delete
from django.contrib.auth.models import User, Group

from .settings import *

logger = logging.getLogger(__name__)

def log(msg):
    logger.debug(msg)
    print(msg)


def adding_nexcloud_user(_user, **kwargs):
    print("pass add nextcloud user")
    # Add new member on the nextcloud server

    _pass = NEXTCLOUD_USER_DEFAULT_PASSWORD

    _admin = NEXTCLOUD_ADMIN
    _admin_key = NEXTCLOUD_PASSWORD    

    _url = '%s://%s' % (('http', 'https')[NEXTCLOUD_USE_HTTPS is True], NEXTCLOUD_HOST)

    nc = NextCloudCLI.Client(_url, verify_certs=NEXTCLOUD_SSL_IS_SIGNED)
    _err = ['login', 'create_user', 'enable_user', 'add_user_to_group', 'set_user_attribute quota']
    try:
        nc.login(_admin, _admin_key)
        print("pass logged")
        _err.pop(0)
        try:
            print(f"NC User Created  {_user.username} / {_pass}")
            nc.create_user(_user.username, _pass)
            print(f"**NC User Created passed {_user.username} / {_pass}")
            _err.pop(0)
        except NextCloudCLI.OCSResponseError as e:
            if e.status_code == 102:
                _err.pop(0)
                nc.make_ocs_request('PUT', 'cloud/users', _user.username + '/enable')
            else:
                raise e
        _err.pop(0)
        if NEXTCLOUD_USER_GROUP is not None:
            nc.add_user_to_group(_user.username, NEXTCLOUD_USER_GROUP)
        _err.pop(0)
        if NEXTCLOUD_USER_QUOTA is not None:
            nc.set_user_attribute(_user.username, 'quota', NEXTCLOUD_USER_QUOTA)
        nc.logout()

    except NextCloudCLI.HTTPResponseError as e:
        log('adding_nexcloug_user: %s HTTP Error %d' % (_err[0], e.status_code))
    except requests.exceptions.ConnectionError as e:
        log('adding_nexcloug_user: %s Connection Error: %s' % (_err[0], e))
    except NextCloudCLI.OCSResponseError as e:
        log('adding_nexcloug_user: %s OCSResponse Error %d' % (_err[0], e.status_code))
    else:
        log('Adding user %s success' % _user.username)


@receiver(post_delete, sender= User)
def deactivating_nexcloud_user(instance, **kwargs):
    # Remove member on the nextcloud server
    _user = instance

    _admin = NEXTCLOUD_ADMIN
    _admin_key = NEXTCLOUD_PASSWORD

    _url = ('http', 'https')[NEXTCLOUD_USE_HTTPS is True] + '://' + NEXTCLOUD_HOST

    nc = NextCloudCLI.Client(_url, verify_certs=NEXTCLOUD_SSL_IS_SIGNED)
    _err = ['login', 'deactivate_user']
    try:
        nc.login(_admin, _admin_key)
        _err.pop(0)
        nc.make_ocs_request('PUT', 'cloud/users', _user.username + '/disable')
        nc.logout()

    except NextCloudCLI.HTTPResponseError as e:
        log('removing_nexcloug_user: %s HTTP Error %d' % (_err[0], e.status_code))
    except requests.exceptions.ConnectionError as e:
        log('removing_nexcloug_user: %s Connection Error: %s' % (_err[0], e))
    except NextCloudCLI.OCSResponseError as e:
        log('removing_nexcloug_user: %s OCSResponse Error %d' % (_err[0], e.status_code))
    else:
        log('Removing user %s success' % _user.username)
        print('Removing user %s success' % _user.username)



def update_nexcloud_user(_user, **kwargs):
    log(f"User edited {_user}")
    # Change user password on the nextcloud server


    _admin = NEXTCLOUD_ADMIN
    _admin_key = NEXTCLOUD_PASSWORD
    print(f"NEXTCLOUD_ADMIN={NEXTCLOUD_ADMIN} / NEXTCLOUD_PASSWORD{NEXTCLOUD_PASSWORD} / NEXTCLOUD_HOST{NEXTCLOUD_HOST}")
    _url = ('http', 'https')[NEXTCLOUD_USE_HTTPS is True] + '://' + NEXTCLOUD_HOST

    nc = NextCloudCLI.Client(_url, verify_certs=NEXTCLOUD_SSL_IS_SIGNED)
    _err = ['login', 'set_user_attribute password']
    try:
        nc.login(_admin, _admin_key)
        _err.pop(0)
        nc.set_user_attribute(_user.username, 'email', _user.email)
        nc.set_user_attribute(_user.username, 'displayname', _user.first_name + " " + _user.last_name + get_pseudonyme_from_user(_user.username))
        _groups = _user.groups.values_list('name', flat=True)
        groups = list(_groups)
        for grp in groups:
            log(f"add a group [{grp}] for {_user}")
            nc.add_user_to_group(_user.username, grp)
        nc.logout()

    except NextCloudCLI.HTTPResponseError as e:
        log('changing_nexcloud_user_password: %s HTTP Error %d' % (_err[0], e.status_code))
        print(f"ERROR =====> {e}")
    except requests.exceptions.ConnectionError as e:
        log('changing_nexcloud_user_password: %s Connection Error: %s' % (_err[0], e))
    except NextCloudCLI.OCSResponseError as e:
        log('changing_nexcloud_user_password: %s OCSResponse Error %d' % (_err[0], e.status_code))
    else:
        log('Update user %s success' % _user.username)

def get_pseudonyme_from_user(username):
    print(username)
    if "mc" in username:
        return " (" + username.split("@")[0].replace("mc","MC") + ")"
    else:
        return ""

@receiver(post_save, sender= User)
def post_save_User_handler(created,instance, **kwargs):
    print(f"Signal post_save reçu pour l'utilisateur : {instance.username}, créé : {created}")
    _user = instance
    if created:
        adding_nexcloud_user(_user=_user)
    else:
        update_nexcloud_user(_user=_user)
@receiver(post_save, sender= Group)
def adding_nexcloud_group(sender,instance,created, **kwargs):
    print(f"Signal post_save reçu pour le groupe : {instance.name}, créé : {created}")
    if not created:
        log(f"group Edited {instance.name}")
        return False
    # Add new member on the nextcloud server
    _group = instance


    _admin = NEXTCLOUD_ADMIN
    _admin_key = NEXTCLOUD_PASSWORD

    _url = '%s://%s' % (('http', 'https')[NEXTCLOUD_USE_HTTPS is True], NEXTCLOUD_HOST)

    nc = NextCloudCLI.Client(_url, verify_certs=NEXTCLOUD_SSL_IS_SIGNED)
    _err = ['login', 'create_group', 'enable_group']
    try:
        nc.login(_admin, _admin_key)
        print("pass logged")
        _err.pop(0)
        try:
            nc.create_group(_group.name)
            _err.pop(0)
        except NextCloudCLI.OCSResponseError as e:
            if e.status_code == 102:
                _err.pop(0)
            else:
                raise e
        _err.pop(0)
        nc.logout()

    except NextCloudCLI.HTTPResponseError as e:
        log('adding_nexcloug_group: %s HTTP Error %d' % (_err[0], e.status_code))
    except requests.exceptions.ConnectionError as e:
        log('adding_nexcloug_group: %s Connection Error: %s' % (_err[0], e))
    except NextCloudCLI.OCSResponseError as e:
        log('adding_nexcloug_group: %s OCSResponse Error %d' % (_err[0], e.status_code))
    else:
        log('Adding group %s success' % _group.name)

@receiver(post_delete, sender= Group)
def delete_nexcloud_group(sender,instance, **kwargs):
    print("Remove group")
    # Remove member on the nextcloud server
    _group = instance

    _admin = NEXTCLOUD_ADMIN
    _admin_key = NEXTCLOUD_PASSWORD

    _url = ('http', 'https')[NEXTCLOUD_USE_HTTPS is True] + '://' + NEXTCLOUD_HOST

    nc = NextCloudCLI.Client(_url, verify_certs=NEXTCLOUD_SSL_IS_SIGNED)
    _err = ['login', 'deactivate_user']
    try:
        nc.login(_admin, _admin_key)
        _err.pop(0)
        nc.delete_group(_group.name)
        nc.logout()

    except NextCloudCLI.HTTPResponseError as e:
        log('removing_nexcloug_group: %s HTTP Error %d' % (_err[0], e.status_code))
    except requests.exceptions.ConnectionError as e:
        log('removing_nexcloug_group: %s Connection Error: %s' % (_err[0], e))
    except NextCloudCLI.OCSResponseError as e:
        log('removing_nexcloug_group: %s OCSResponse Error %d' % (_err[0], e.status_code))
    else:
        log('Removing group %s success' % _group.name)
