# -*- coding: utf-8 -*-
from django.db import transaction


class CoinLdapSyncMixin(object):

    """
    Ce mixin est à utiliser lorsqu'il s'agit de définir un modèle
    à synchroniser avec le LDAP. Le modèle doit définir les méthodes :
    sync_to_ldap et delete_from_ldap qui s'occupent du transfert vers le LDAP.
    L'avantage de ce modèle est que si cette méthode échoue, la sauvegarde en
    base de données échoue à son tour et rien n'est sauvegardé afin de conserver
    la cohérence entre base de donnée et LDAP
    """

    def sync_to_ldap(self, creation):
        raise NotImplementedError('Using CoinLdapSyncModel require '
                                  'sync_to_ldap method being implemented')


    def delete_from_ldap(self):
        raise NotImplementedError('Using CoinLdapSyncModel require '
                                  'delete_from_ldap method being implemented')

    @transaction.atomic
    def save(self, *args, **kwargs):
        # Détermine si on est dans une création ou une mise à jour
        creation = (self.pk == None)

        # Sauvegarde en base de donnée (mais sans commit, cf decorator)
        super(CoinLdapSyncMixin, self).save(*args, **kwargs)

        # Sauvegarde dans le LDAP
        # Si la sauvegarde LDAP échoue, Rollback la sauvegarde en base, sinon
        # commit
        try:
            self.sync_to_ldap(creation)
        except:
            raise

    @transaction.atomic
    def delete(self, *args, **kwargs):
        # Supprime de la base de donnée (mais sans commit, cf decorator)
        super(CoinLdapSyncMixin, self).delete(*args, **kwargs)

        try:
            self.delete_from_ldap()
        except:
            raise
