# -*- coding: utf-8 -*-
import logging
import boto3
import yenv
import json
import os

from django.conf import settings

from idm.core.management.base import IdmBaseCommand
from idm.core.models import System, Role

log = logging.getLogger(__name__)


class Command(IdmBaseCommand):
    help = """Заливаем в S3-MDS данные ролей для webauth"""

    def _upload_roles(self, roles_by_system):
        session = boto3.session.Session(
            aws_access_key_id=settings.MDS_ACCESS_KEY_ID,
            aws_secret_access_key=settings.MDS_SECRET_ACCESS_KEY,
        )
        s3 = session.client(
            service_name='s3',
            endpoint_url='https://s3.mds.yandex.net',
        )

        s3.put_object(
            Bucket='webauth-roles',
            Key=f'{yenv.type}_webauth_roles_latest',
            Body=json.dumps(roles_by_system),
        )
        log.info('Successfully upload cache for Webauth')

    def idm_handle(self, *args, **options):
        log.info('Uploading cache for Webauth')
        systems = System.objects.filter(use_webauth=True)
        roles_by_system = {}
        for system in systems:
            role_count = 0
            roles = Role.objects.filter(
                system=system,
                is_active=True,
                user_id__isnull=False,
            ).select_related('user', 'node').values_list(
                'fields_data',
                'node__value_path',
                'user__username',
            ).iterator()

            nodes = {}
            for fields_data, value_path, username in roles:
                node_path = os.path.join(system.slug, value_path)
                if isinstance(fields_data, dict):
                    fields_data = tuple((key, value) for key, value in fields_data.items())
                if node_path not in nodes:
                    nodes[node_path] = set()

                nodes[node_path].add((username, fields_data or tuple()))
                role_count+=1

            for node_path in nodes:
                nodes[node_path] = list(nodes[node_path])

            roles_by_system[system.slug] = nodes
            log.info(f'Got {len(nodes)} nodes with {role_count} roles for {system.slug}')

        if not roles_by_system:
            log.warning('No roles for Webauth found')
            return

        self._upload_roles(roles_by_system)
