package org.apache.commons.jcs.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.jcs.engine.control.event.behavior.IElementEvent;
import org.apache.commons.jcs.engine.control.event.behavior.IElementEventHandler;
import org.apache.commons.jcs.engine.control.event.behavior.IElementEventQueue;
import org.apache.commons.jcs.log.Log;
import org.apache.commons.jcs.log.LogManager;
import org.apache.commons.jcs.utils.threadpool.PoolConfiguration;
import org.apache.commons.jcs.utils.threadpool.PoolConfiguration.WhenBlockedPolicy;
import org.apache.commons.jcs.utils.threadpool.ThreadPoolManager;

/**
 * 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( IElementEventHandler hand, 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
        {
            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 ( 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( IElementEventHandler hand, 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 );
        }
    }
}
