import base64
import logging
import string
from secrets import choice

import requests
from django.conf import settings

_log = logging.getLogger(__name__)


class RabbitMQUserManagement:
    def __init__(self, uuid):
        self.uuid = uuid

    def create_random_rabbitmq_credentials(self):
        """Create a username and password to connect to RabbitMQ"""

        username = f'sensor_{self.uuid}'
        password = ''.join(choice(string.ascii_uppercase + string.digits) for i in range(20))

        source_credentials = username + '@@' + password

        credentials_bytes = source_credentials.encode()
        b64_credentials = base64.b64encode(credentials_bytes)
        final_credentials = b64_credentials.decode()

        self._create_rabbitmq_user(username, password)
        self._set_rabbitmq_permissions(username)

        return final_credentials

    @staticmethod
    def _create_rabbitmq_user(username, password):
        data = {
            'password': password,
            'tags': ''
        }
        response = requests.put(f'http://{settings.RABBIT_HOST}:15672/api/users/{username}/',
                                auth=('guest', 'guest'),
                                json=data)
        if response.ok:
            _log.info(f'RabbitMQ user {username} created')
        else:
            _log.error(f'Error creating RabbitMQ user {username}')

    @staticmethod
    def _set_rabbitmq_permissions(username):
        vhost = '%2F'  # стандартный хост, на котором находится сервер RabbitMQ. это просто закодированный слэш "/"

        # https://www.rabbitmq.com/access-control.html#authorisation
        data = {
            # юзер может кофигурировать (создавать. удалять, изменять) только свою очередь
            "configure": username,

            # может писать в автоматически сгенерированные очереди или в свою
            "write": f'^(amq.gen.*|amq.default|{username})$',

            # может читать из своей очереди или из общей для всех сенсоров
            "read": f"sensors|{username}"
        }
        response = requests.put(f'http://{settings.RABBIT_HOST}:15672/api/permissions/{vhost}/{username}/',
                                auth=('guest', 'guest'),
                                json=data)
        if response.ok:
            _log.info(f'Set permissions for RabbitMQ user {username}')
        else:
            _log.error(f'Error setting permissions for RabbitMQ user {username}')
