#!/usr/bin/env python3
import pika
import dbus
from random import randint
from time import sleep

server_host = 'rabbitmq.edu-al.unipmn.it';
server_port = 5672;
server_username = 'labmanager-client';
server_pwd = '3aB7=2zV9:1jN3-4hE2';
server_vhost = 'labmanager';

exchange_name = 'labmanager-test';
exchange_type = 'x-recent-history'; # It's a plugin. Enable with 'rabbitmq-plugins enable rabbitmq_recent_history_exchange'

systemd_getconfig_unit_name = 'esame-get-config.service'

bus = dbus.SystemBus()
systemd = bus.get_object(
    'org.freedesktop.systemd1',
    '/org/freedesktop/systemd1'
)

manager = dbus.Interface(
    systemd,
    'org.freedesktop.systemd1.Manager'
)

server_credentials = pika.PlainCredentials(server_username, server_pwd, True)

while True:
    try:

        connection = pika.BlockingConnection(
            pika.ConnectionParameters(
                host=server_host,
                port=server_port,
                virtual_host=server_vhost,
                credentials=server_credentials
            )
        )

        channel = connection.channel()

        '''
        L'exchange lo dichiara il publisher
        TODO: qui serve sapere se esiste gia' e in caso negativo aspettare e ripetere (valutare se usare passive=true)
        '''
        # channel.exchange_declare(exchange=exchange_name, exchange_type=exchange_type)

        result = channel.queue_declare(queue='', exclusive=True)
        queue_name = result.method.queue

        channel.queue_bind(exchange=exchange_name, queue=queue_name)

        print('Waiting for RabbitMQ messages')

        def callback(ch, method, properties, body):
            # Sleep a random number of seconds (between 1 and 10)
            # to avoid all machines reboot at the same time
            sleep(randint(1,10))
            
            print("RabbitMQ message: %s" % body.decode('UTF-8'))
            start_unit = manager.StartUnit(systemd_getconfig_unit_name, 'fail')

        channel.basic_consume(
            queue=queue_name, on_message_callback=callback, auto_ack=True)

        channel.start_consuming()

    except pika.exceptions.ConnectionClosedByBroker:
        break
    # Don't recover on channel errors
    except pika.exceptions.AMQPChannelError:
        break
    # Recover on all other connection errors
    except pika.exceptions.AMQPConnectionError:
        continue