package dst.ass3.messaging.impl;

import com.rabbitmq.client.BuiltinExchangeType;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import dst.ass3.messaging.Constants;
import dst.ass3.messaging.IQueueManager;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

public class QueueManager implements IQueueManager {
    @Override
    public void setUp() {
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost(Constants.RMQ_HOST);
        factory.setPort(Integer.parseInt(Constants.RMQ_PORT));
        factory.setUsername(Constants.RMQ_USER);
        factory.setPassword(Constants.RMQ_PASSWORD);

        try {
            Connection conn = factory.newConnection();
            Channel channel = conn.createChannel();
            channel.exchangeDeclare(Constants.TOPIC_EXCHANGE, BuiltinExchangeType.TOPIC, true);

            for (String qname : Constants.WORK_QUEUES) {
                channel.queueDeclare(qname, true, false, false, null);
            }

            channel.close();
            conn.close();
        } catch (IOException | TimeoutException e) {
            throw new RuntimeException("Irrecoverable error", e); // Fail horribly
        }
    }

    @Override
    public void tearDown() {
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost(Constants.RMQ_HOST);
        factory.setPort(Integer.parseInt(Constants.RMQ_PORT));
        factory.setUsername(Constants.RMQ_USER);
        factory.setPassword(Constants.RMQ_PASSWORD);

        try {
            Connection conn = factory.newConnection();
            Channel channel = conn.createChannel();
            channel.exchangeDelete(Constants.TOPIC_EXCHANGE);

            for (String qname : Constants.WORK_QUEUES) {
                channel.queueDelete(qname);
            }

            channel.close();
            conn.close();
        } catch (IOException | TimeoutException e) {
            throw new RuntimeException("Irrecoverable error", e); // Fail horribly
        }
    }

    @Override
    public void close() throws IOException {
        tearDown(); // TODO: unsure if needed.
    }
}
