# coding: utf-8


import logging

from django.utils import timezone

from idm.core.models import Action
from idm.core.models import RoleNode
from idm.framework.requester import requesterify
from idm.framework.utils import add_to_instance_cache
from idm.utils.lock import lock

log = logging.getLogger(__name__)


def update_sync_end(sync_key):
    if sync_key is None:
        return False

    try:
        end_action = Action.objects.get(parent=sync_key, action='role_tree_synced')
    except (Action.DoesNotExist, Action.MultipleObjectsReturned):
        return False

    deleted_count = Action.objects.filter(parent=sync_key, action='role_node_deleted').count()
    try:
        end_action.data['report']['nodes_deleted'] = deleted_count
    except KeyError:
        return False

    end_action.save()
    return True


def deprive_nodes(system, requester=None, sync_key=None, from_api=False):
    """Функция отзывает роли, связанные с узлами, находящимися в статусе depriving."""

    with lock('idm.utils.rolenode.deprive_nodes:%s' % system.slug, block=False) as acquired:
        if not acquired:
            log.info('Cannot deprive role nodes of system "%s": lock cannot be acquired', system.slug)
            return

        requester = requesterify(requester)

        log.info('Starting depriving nodes for system %s', system.slug)
        start_time = timezone.now()
        system.metainfo.last_deprive_nodes_start = start_time
        system.metainfo.save(update_fields=('last_deprive_nodes_start',))
        nodes_to_deprive = RoleNode.objects.depriving().filter(system=system, depriving_at__lte=start_time)
        for rolenode in nodes_to_deprive:
            add_to_instance_cache(rolenode, 'system', system)
            rolenode.deprive(requester, sync_key, from_api=from_api)

        # обновляем role_tree_synced, если он есть
        updated = update_sync_end(sync_key)
        if updated:
            log.info('Updated report with nodes_deleted when depriving nodes in system %s.', system.slug)
        else:
            log.info('Could not update report with nodes_deleted when depriving nodes in system %s.', system.slug)

        end_time = timezone.now()
        system.metainfo.last_deprive_nodes_finish = end_time
        system.metainfo.save(update_fields=('last_deprive_nodes_finish',))
        log.info('Depriving nodes for system %s finished. Depriving time: %s', system.slug, end_time - start_time)
