import logging

from blackbox import FIELD_SUID

from idm.core.constants.passport_login import PASSPORT_LOGIN_STATE
from idm.core.management.base import IdmBaseCommand
from idm.core.models import UserPassportLogin
from idm.monitorings.metric import UnsubscribedLoginsMetric
from idm.sync.passport import get_external_blackbox
from idm.utils.replication import use_slave

log = logging.getLogger(__name__)


class Command(IdmBaseCommand):
    help = 'Проверяет, что паспортные логины в статусе \'subscribed\' действительно подписаны в паспорте'
    intranet_only = True

    def add_arguments(self, parser):
        super(Command, self).add_arguments(parser)
        parser.add_argument(
            '--fix', action='store', dest='fix', required=False,
            help='Подписать указанные логины (перечисление через запятую)',
        )
        parser.add_argument(
            '--fix-all',
            action='store_true',
            dest='fix_all',
            default=False,
            help='Подписать найденные логины',
        )

    @use_slave()
    def idm_handle(self, *args, **options):
        fix = options.get('fix', None)
        fix_all = options.get('fix_all', False)

        if fix:
            logins_to_fix = [login.strip() for login in fix.split(',')]
            UserPassportLogin.objects.subscribe_logins(logins=logins_to_fix)
            return

        passport = get_external_blackbox()
        logins = UserPassportLogin.objects.subscribed()

        not_subscribed = set()
        for login in logins:
            userinfo = passport.userinfo(
                login.login,
                None,
                by_login=True,
                dbfields=[FIELD_SUID(67)]
            )
            if not userinfo['uid']:
                # вообще такую учетку не нашли
                log.warning('No user with such login in blackbox: {}'.format(login.login))
                continue

            subscribed = userinfo['fields']['suid'] == '1'
            if not subscribed:
                login.refresh_from_db()  # могли снять сид в другой таске, так что тут получим свежий объект
                if login.state == PASSPORT_LOGIN_STATE.SUBSCRIBED:
                    not_subscribed.add(login)

        result = ''
        if not_subscribed:
            if fix_all:
                log.info('Subscribing passport logins: {}'.format(
                    ', '.join(l.login for l in not_subscribed)
                ))
                UserPassportLogin.objects.subscribe_logins(logins=not_subscribed)
                return

            result = 'IDM has {} passport logins in subscribed state, but actually not subscribed: {}'.format(
                len(not_subscribed),
                ', '.join(l.login for l in not_subscribed),
            )
        log.info(result if result else 'IDM has 0 subscribed logins actually not subscribed')

        UnsubscribedLoginsMetric.set(result)
