package my.webapp.pack.services;

import org.apache.tapestry5.ioc.annotations.Inject;
import org.apache.tapestry5.ioc.annotations.PostInjection;
import org.apache.tapestry5.ioc.services.RegistryShutdownHub;
import org.slf4j.Logger;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * User: robert
 * Date: 2013/04/04
 * Time: 5:25 PM
 */
public class OrderedShutdownHubImpl implements OrderedShutdownHub
{
    public
    void registerShutdownListener(int order, Runnable runnable)
    {
        synchronized (callbacks) {
            callbacks.add(new Entry(order, runnable));
        }
    }

    private List<Entry> callbacks;

    @Inject
    private Logger log;

    private
    void registryWillShutdown()
    {
        log.debug("registry will shutdown");
        Collections.sort(callbacks);

        for (Entry entry : callbacks)
        {
            log.debug("shutdown order: {}", entry.order);
            try {
                entry.runnable.run();
            } catch (Exception e) {
                log.error("shutdown hook threw exception", e);
            }
        }

        log.debug("ordered shutdown complete");
    }


    @PostInjection
    public
    void serviceStart(RegistryShutdownHub registryShutdownHub)
    {
        callbacks=new ArrayList<Entry>();

        registryShutdownHub.addRegistryWillShutdownListener(new Runnable()
        {
            public void run()
            {
                registryWillShutdown();
            }
        });

    }

    private static
    class Entry implements Comparable<Entry>
    {
        final int order;
        final Runnable runnable;

        private
        Entry(int order, Runnable runnable)
        {
            this.order = order;
            this.runnable = runnable;
        }

        public
        int compareTo(Entry e)
        {
            return (order - e.order);
        }
    }
}
