import pika
import functools
from threading import Thread
from deprecated import deprecated
import network_constants as netconst

import logging
LOGGER = logging.getLogger(__name__)

@deprecated(reason='BlockingConnection has connection timeout. Use ReconnectingMessageManager instead.')
class MessageSender:
    
    _rabbit_mq_ip = None
    _rabbit_mq_port = None

    _connection: pika.BlockingConnection = None
    _channel: pika.channel.Channel = None

    def __init__(self, rabbit_mq_ip=netconst.RABBIT_MQ_HOSTNAME, rabbit_mq_port=netconst.RABBIT_MQ_PORT):
        self._rabbit_mq_ip = rabbit_mq_ip
        self._rabbit_mq_port = rabbit_mq_port

    def connect(self):
        '''Connects to RabbitMQ'''
        self._connection = pika.BlockingConnection(parameters=pika.ConnectionParameters(self._rabbit_mq_ip, self._rabbit_mq_port, heartbeat=60, blocked_connection_timeout=30))
        self._channel = self._connection.channel()
        LOGGER.info(f"RabbitMQ connection established")

    def create_exchange(self, exchange_name, exchange_type):
        '''Creates the exchange if not existent'''
        self._channel.exchange_declare(exchange=exchange_name, exchange_type=exchange_type)

    def send(self, exchange_name, message, routing_key=''):
        '''Sends a message to the exchange'''
        if self._channel == None:
            LOGGER.error("Tried to send before connection to RabbitMQ was established")
            raise RuntimeError("Connection to RabbitMQ not established, call MessageSender.connect() first")

        # TODO connection is closed after 60s   
        self._channel.basic_publish(exchange=exchange_name, routing_key=routing_key, body=message)

    def disconnect(self):
        '''Disconnects from RabbitMQ'''
        if self._connection == None:
            LOGGER.error("Tried to close connection before connection to RabbitMQ was established")
            raise RuntimeError("Connection to RabbitMQ not established")

        self._connection.close()
        LOGGER.info(f"RabbitMQ connection closed")