package com.agilex.healthcare.schedulingmanager.notification.appointmentrequest;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.DisposableBean;

import com.agilex.messaging.provider.beanstalk.BeanstalkBus;
import com.agilex.messaging.provider.beanstalk.Queue;
import com.agilex.messaging.provider.beanstalk.config.BeanstalkBusInfo;

/**
 * Created with IntelliJ IDEA.
 * User: clarkee
 * Date: 2/25/13
 * Time: 10:36 AM
 * To change this template use File | Settings | File Templates.
 */
public class BatchEmailNotificationWorker implements DisposableBean {
    private final static Log logger = LogFactory.getLog(BatchEmailNotificationWorker.class);
    private BatchEmailNotificationMessageHandler handler;
    private HaMessagingConfiguration configuration;
    private BeanstalkBus queue;
    private boolean isSubscribed = false;
    private boolean queueStarted = false;

    //A queue instance should should only be started/stopped once
    //appears the queue.ctor(), queue.subscribe(), queue.start() flow must be followed
    public BatchEmailNotificationWorker(HaMessagingConfiguration configuration, BatchEmailNotificationMessageHandler handler) {

        this.configuration = configuration;
        this.handler = handler;
    }

    private void initqueue() {
        if (configuration.isEnabled()){
            queue = new BeanstalkBus(new BeanstalkBusInfo(configuration.getQueueName(), configuration));
        }
    }

    public void beginProcessing() {
        logger.debug("beginProcessing()");

        initqueue();
        subscribe();
        startqueue();

        logger.debug("beginProcessing() finished");
    }

    public void stopProcessing() {
        logger.debug("stopProcessing()");

        stopqueue();
        unsubscribe();
        queue = null;

        logger.debug("stopProcessing() finished");
    }

    private void startqueue() {
        if (!queueStarted){
            if (configuration.isEnabled() && !queueStarted) {
                try {
                    logger.debug("queue " + queue.info().name() + " starting");
                    queue.start();
                    logger.debug("queue " + queue.info().name() + " started");
                } catch (Exception e) {
                    logger.debug(e.getMessage());
                }
            }
        }
        queueStarted = true;
    }

    private void stopqueue() {
        if (configuration.isEnabled() && queueStarted) {
            try {
                logger.debug("queue" + queue.info().name() + " stopping");
                queue.stop();
                logger.debug("queue" + queue.info().name() + " stopped");
            } catch (Exception e) {
                logger.debug("Error stopping queue " + queue.info().name());
                logger.debug(e.getMessage());
            }
        }
        queueStarted = false;
    }

    private void subscribe() {
        if (configuration.isEnabled()) {
            if (!isSubscribed){
                logger.debug("Subscribing queue " + queue.info().name() + ", Handler " + handler.getClass().getName());
                queue.subscribe(Queue.createDestination(configuration.getQueueName()), handler);
                handler.clearProcessedEmails();
                isSubscribed = true;
            }
        }
    }

    private void unsubscribe() {
        if (configuration.isEnabled()) {
            if (isSubscribed){
                logger.debug("Unsubscribing queue " + queue.info().name() + ", Handler " + handler.getClass().getName());
                queue.unsubscribe(this.handler);
                handler.clearProcessedEmails();
                isSubscribed = false;
            }
        }
    }

    @Override
    public void destroy() throws Exception {
        stopProcessing();
    }
}
