/*
 * 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.
 */
package org.apache.felix.eventadmin.impl;

import org.apache.felix.eventadmin.impl.dispatch.DefaultThreadPool;
import org.apache.felix.eventadmin.impl.handler.HandlerTasks;
import org.apache.felix.eventadmin.impl.tasks.*;
import org.osgi.service.event.Event;
import org.osgi.service.event.EventAdmin;

/**
 * This is the actual implementation of the OSGi R4 Event Admin Service (see the
 * Compendium 113 for details). The implementation uses a <tt>HandlerTasks</tt>
 * in order to determine applicable <tt>EventHandler</tt> for a specific event and
 * subsequently dispatches the event to the handlers via <tt>DeliverTasks</tt>.
 * To do this, it uses two different <tt>DeliverTasks</tt> one for asynchronous and
 * one for synchronous event delivery depending on whether its <tt>post()</tt> or
 * its <tt>send()</tt> method is called. Note that the actual work is done in the
 * implementations of the <tt>DeliverTasks</tt>. Additionally, a stop method is
 * provided that prevents subsequent events to be delivered.
 *
 * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
 */
public class EventAdminImpl implements EventAdmin
{
    // The factory used to determine applicable EventHandlers - this will be replaced
    // by a null object in stop() that subsequently throws an IllegalStateException
    private volatile HandlerTasks m_managers;

    // The asynchronous event dispatcher
    private final DeliverTask m_postManager;

    // The synchronous event dispatcher
    private final SyncDeliverTasks m_sendManager;

    /**
     * The constructor of the <tt>EventAdmin</tt> implementation. The
     * <tt>HandlerTasks</tt> factory is used to determine applicable
     * <tt>EventHandler</tt> for a given event. Additionally, the two
     * <tt>DeliverTasks</tt> are used to dispatch the event.
     *
     * @param managers The factory used to determine applicable <tt>EventHandler</tt>
     * @param syncPool The synchronous thread pool
     * @param asyncPool The asynchronous thread pool
     */
    public EventAdminImpl(final HandlerTasks managers,
            final DefaultThreadPool syncPool,
            final DefaultThreadPool asyncPool,
            final int timeout,
            final String[] ignoreTimeout)
    {
        checkNull(managers, "Managers");
        checkNull(syncPool, "syncPool");
        checkNull(asyncPool, "asyncPool");

        m_managers = managers;

        m_sendManager = new SyncDeliverTasks(syncPool,
                (timeout > 100 ? timeout : 0),
                ignoreTimeout);

        m_postManager = new AsyncDeliverTasks(asyncPool, m_sendManager);
    }

    /**
     * Post an asynchronous event.
     *
     * @param event The event to be posted by this service
     *
     * @throws IllegalStateException - In case we are stopped
     *
     * @see org.osgi.service.event.EventAdmin#postEvent(org.osgi.service.event.Event)
     */
    public void postEvent(final Event event)
    {
        handleEvent(m_managers.createHandlerTasks(event), m_postManager);
    }

    /**
     * Send a synchronous event.
     *
     * @param event The event to be send by this service
     *
     * @throws IllegalStateException - In case we are stopped
     *
     * @see org.osgi.service.event.EventAdmin#sendEvent(org.osgi.service.event.Event)
     */
    public void sendEvent(final Event event)
    {
        handleEvent(m_managers.createHandlerTasks(event), m_sendManager);
    }

    /**
     * This method can be used to stop the delivery of events. The m_managers is
     * replaced with a null object that throws an IllegalStateException on a call
     * to <tt>createHandlerTasks()</tt>.
     */
    public void stop()
    {
        // replace the HandlerTasks with a null object that will throw an
        // IllegalStateException on a call to createHandlerTasks
        m_managers = new HandlerTasks()
        {
            /**
             * This is a null object and this method will throw an
             * IllegalStateException due to the bundle being stopped.
             *
             * @param event An event that is not used.
             *
             * @return This method does not return normally
             *
             * @throws IllegalStateException - This is a null object and this method
             *          will always throw an IllegalStateException
             */
            public HandlerTask[] createHandlerTasks(final Event event)
            {
                throw new IllegalStateException("The EventAdmin is stopped");
            }
        };
    }

    /**
     * Update the event admin with new configuration.
     */
    public void update(final HandlerTasks managers, final int timeout,
            final String[] ignoreTimeout)
    {
        m_managers = managers;
        m_sendManager.update(timeout, ignoreTimeout);
    }

    /**
     * This is a utility method that uses the given DeliverTasks to create a
     * dispatch tasks that subsequently is used to dispatch the given HandlerTasks.
     */
    private void handleEvent(final HandlerTask[] managers,
        final DeliverTask manager)
    {
        if (0 < managers.length)
        {
            // This might throw an IllegalStateException in case that we are stopped
            // and the null object for m_managers was not fast enough established
            // This is needed in the adapter/* classes due to them sending
            // events whenever they receive an event from their source.
            // Service importers that call us regardless of the fact that we are
            // stopped deserve an exception anyways
            manager.execute(managers);
        }
    }

    /**
     * This is a utility method that will throw a <tt>NullPointerException</tt>
     * in case that the given object is null. The message will be of the form
     * "${name} + may not be null".
     */
    private void checkNull(final Object object, final String name)
    {
        if(null == object)
        {
            throw new NullPointerException(name + " may not be null");
        }
    }
}
