package org.apache.commons.jcs3.engine.control.event;

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

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

import org.apache.commons.jcs3.engine.control.event.behavior.IElementEvent;
import org.apache.commons.jcs3.engine.control.event.behavior.IElementEventHandler;
import org.apache.commons.jcs3.engine.control.event.behavior.IElementEventQueue;
import org.apache.commons.jcs3.log.Log;
import org.apache.commons.jcs3.log.LogManager;
import org.apache.commons.jcs3.utils.threadpool.PoolConfiguration;
import org.apache.commons.jcs3.utils.threadpool.ThreadPoolManager;
import org.apache.commons.jcs3.utils.threadpool.PoolConfiguration.WhenBlockedPolicy;

/**
 * An event queue is used to propagate ordered cache events to one and only one target listener.
 */
public class ElementEventQueue
    implements IElementEventQueue
{
    private static final String THREAD_PREFIX = "JCS-ElementEventQueue-";

    /** The logger */
    private static final Log log = LogManager.getLog( ElementEventQueue.class );

    /** shutdown or not */
    private boolean destroyed = false;

    /** The worker thread pool. */
    private ExecutorService queueProcessor;

    /**
     * Constructor for the ElementEventQueue object
     */
    public ElementEventQueue()
    {
        queueProcessor = ThreadPoolManager.getInstance().createPool(
        		new PoolConfiguration(false, 0, 1, 1, 0, WhenBlockedPolicy.RUN, 1), THREAD_PREFIX);

        log.debug( "Constructed: {0}", this );
    }

    /**
     * Dispose queue
     */
    @Override
    public void dispose()
    {
        if ( !destroyed )
        {
            destroyed = true;

            // synchronize on queue so the thread will not wait forever,
            // and then interrupt the QueueProcessor
            queueProcessor.shutdownNow();
            queueProcessor = null;

            log.info( "Element event queue destroyed: {0}", this );
        }
    }

    /**
     * Adds an ElementEvent to be handled
     * @param hand The IElementEventHandler
     * @param event The IElementEventHandler IElementEvent event
     * @throws IOException
     */
    @Override
    public <T> void addElementEvent( final IElementEventHandler hand, final IElementEvent<T> event )
        throws IOException
    {

        log.debug( "Adding Event Handler to QUEUE, !destroyed = {0}", !destroyed );

        if (destroyed)
        {
            log.warn("Event submitted to disposed element event queue {0}", event);
        }
        else
        {
            final ElementEventRunner runner = new ElementEventRunner( hand, event );

            log.debug( "runner = {0}", runner );

            queueProcessor.execute(runner);
        }
    }

    // /////////////////////////// Inner classes /////////////////////////////

    /**
     * Retries before declaring failure.
     */
    protected abstract class AbstractElementEventRunner
        implements Runnable
    {
        /**
         * Main processing method for the AbstractElementEvent object
         */
        @SuppressWarnings("synthetic-access")
        @Override
        public void run()
        {
            try
            {
                doRun();
                // happy and done.
            }
            catch ( final IOException e )
            {
                // Too bad. The handler has problems.
                log.warn( "Giving up element event handling {0}", ElementEventQueue.this, e );
            }
        }

        /**
         * This will do the work or trigger the work to be done.
         * <p>
         * @throws IOException
         */
        protected abstract void doRun()
            throws IOException;
    }

    /**
     * ElementEventRunner.
     */
    private class ElementEventRunner
        extends AbstractElementEventRunner
    {
        /** the handler */
        private final IElementEventHandler hand;

        /** event */
        private final IElementEvent<?> event;

        /**
         * Constructor for the PutEvent object.
         * <p>
         * @param hand
         * @param event
         * @throws IOException
         */
        @SuppressWarnings("synthetic-access")
        ElementEventRunner( final IElementEventHandler hand, final IElementEvent<?> event )
            throws IOException
        {
            log.debug( "Constructing {0}", this );
            this.hand = hand;
            this.event = event;
        }

        /**
         * Tells the handler to handle the event.
         * <p>
         * @throws IOException
         */
        @Override
        protected void doRun()
            throws IOException
        {
            hand.handleElementEvent( event );
        }
    }
}
