# coding: utf-8


import logging

from django.utils.translation import ugettext_lazy as _

from idm.core.models import Role, RoleNode
from idm.core.plugins.generic import Plugin as GenericPlugin, PluginField
from idm.users.models import User
from idm.utils.check_switch import check_switch
from idm.core.exceptions import PushDisabled

log = logging.getLogger(__name__)


class Plugin(GenericPlugin):
    """Это плагин для систем, которые поддерживают стандартный API и подключены в Коннекте"""

    ROLE_PUSH_SCHEMA = [
        PluginField(key='role', src_key='role_data', json=True),
        PluginField(key='fields', src_key='fields_data', json=True),
        PluginField(key='path'),
        PluginField(key='org_id'),
        PluginField(key='id', src_key='username', optional=True),
        PluginField(key='subject_type', optional=True),
        PluginField(key='uid', optional=True),
    ]

    @check_switch('disable_pushes_all', 'disable_pushes_add_roles', raise_=PushDisabled())
    def add_role(self, **kwargs):
        if not kwargs.get('username'):
            # ToDo: поправить, если в Коннекте появятся групповые роли
            raise NotImplementedError('Group roles not implemented')
        assert kwargs.get('subject_type') is not None
        push_data = self.make_push_data(self.ROLE_PUSH_SCHEMA, kwargs)
        self.log_push(push_data, ident='user uid %s' % kwargs.get('username'))
        return self._post_data('add-role', push_data)

    @check_switch('disable_pushes_all', 'disable_pushes_remove_roles', raise_=PushDisabled())
    def remove_role(self, **kwargs):
        username = kwargs.get('username')
        if not username:
            # ToDo: поправить, если в Коннекте появятся групповые роли
            raise NotImplementedError('Group roles not implemented')
        assert kwargs.get('subject_type') is not None
        push_data = self.make_push_data(self.ROLE_PUSH_SCHEMA, kwargs, for_remove=True)
        self.log_push(push_data, for_remove=True, ident=f'user uid {username}')
        return self._post_data('remove-role', push_data)

    def _check_response_status_code(self, response):
        # ToDo: переопределить, если Коннект даст список кодов, которые не нужно ретраить
        super(Plugin, self)._check_response_status_code(response)

    def import_roles(self, organization, resource_id):
        robot = User.objects.get_idm_robot()
        nodes_cache = {}
        for role in self.get_roles(data={'resource_id': resource_id}):
            try:
                path = role['path']
                if path not in nodes_cache:
                    nodes_cache[path] = RoleNode.objects.get_node_by_slug_path(self.system.pk, path)

                Role.objects.request_role(
                    organization=organization,
                    requester=robot,
                    subject=User.objects.get(username=role['login']),
                    system=self.system.get_self(),
                    comment=_('Ресурс привязан к организации'),
                    data=nodes_cache[path],
                    fields_data={'resource_id': resource_id}
                )
            except Exception:
                log.exception(
                    'Exception during import_roles for system %s resource_id %s', self.system.slug, resource_id
                )
