/*
 * 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.log4j.plugins;

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

import org.apache.log4j.spi.LoggerRepository;
import org.apache.log4j.spi.LoggerRepositoryEx;
import org.apache.log4j.spi.LoggerRepositoryEventListener;


/**
 * This is a registry for Plugin instances. It provides methods to
 * start and stop plugin objects individually and to stop all
 * plugins for a repository.
 *
 * @author Mark Womack
 * @author Paul Smith
 */
public final class PluginRegistry {
    /**
     * The pluginMap is keyed by plugin name and contains plugins as values.
     * key=plugin.getName, value=plugin
     */
    private final Map<String, Plugin> pluginMap;
    /**
     * Logger repository.
     */
    private final LoggerRepositoryEx loggerRepository;

    /**
     * the listener used to listen for repository events.
     */
    private final RepositoryListener listener = new RepositoryListener();
    /**
     * List of listeners.
     */
    private final List listenerList =
            Collections.synchronizedList(new ArrayList());

    /**
     * Creates a new instance.
     * @param repository logger repository.
     */
    public PluginRegistry(final LoggerRepositoryEx repository) {
        super();
        pluginMap = new HashMap<>();
        this.loggerRepository = repository;
        this.loggerRepository.addLoggerRepositoryEventListener(listener);
    }

    /**
     * Get logger repository.
     * @return logger repository.
     */
    public LoggerRepositoryEx getLoggerRepository() {
        return loggerRepository;
    }


    /**
     * Returns true if the specified name is already taken by
     * an existing Plugin registered within the scope of the specified
     * LoggerRepository.
     *
     * @param name The name to check the repository for
     * @return true if the name is already in use, otherwise false
     */
    public boolean pluginNameExists(final String name) {
        synchronized (pluginMap) {
            return pluginMap.containsKey(name);
        }
    }


    /**
     * Adds a plugin to the plugin registry.
     * If a plugin with the same name exists
     * already, it is shutdown and removed.
     *
     * @param plugin the plugin to add.
     */
    public void addPlugin(final Plugin plugin) {
        // put plugin into the repository's reciever map
        synchronized (pluginMap) {
            String name = plugin.getName();

            // make sure the plugin has reference to repository
            plugin.setLoggerRepository(getLoggerRepository());

            Plugin existingPlugin = pluginMap.get(name);
            if (existingPlugin != null) {
                existingPlugin.shutdown();
            }

            // put the new plugin into the map
            pluginMap.put(name, plugin);
            firePluginStarted(plugin);
        }
    }


    /**
     * Calls the pluginStarted method on every registered PluginListener.
     *
     * @param plugin The plugin that has been started.
     */
    private void firePluginStarted(final Plugin plugin) {
        PluginEvent e = null;
        synchronized (listenerList) {
            for (Object aListenerList : listenerList) {
                PluginListener l = (PluginListener) aListenerList;
                if (e == null) {
                    e = new PluginEvent(plugin);
                }
                l.pluginStarted(e);
            }
        }
    }


    /**
     * Calls the pluginStopped method for every registered PluginListner.
     *
     * @param plugin The plugin that has been stopped.
     */
    private void firePluginStopped(final Plugin plugin) {
        PluginEvent e = null;
        synchronized (listenerList) {
            for (Object aListenerList : listenerList) {
                PluginListener l = (PluginListener) aListenerList;
                if (e == null) {
                    e = new PluginEvent(plugin);
                }
                l.pluginStopped(e);
            }
        }
    }


    /**
     * Returns all the plugins for a given repository.
     *
     * @return List list of plugins from the repository.
     */
    public List<Plugin> getPlugins() {
        synchronized (pluginMap) {
            List<Plugin> pluginList = new ArrayList<>(pluginMap.size());

            pluginList.addAll(pluginMap.values());
            return pluginList;
        }
    }


    /**
     * Returns all the plugins for a given repository that are instances
     * of a certain class.
     *
     * @param pluginClass the class the plugin must implement to be selected.
     * @return List list of plugins from the repository.
     */
    public List getPlugins(final Class pluginClass) {
        synchronized (pluginMap) {
            List pluginList = new ArrayList(pluginMap.size());

            for (Object plugin : pluginMap.values()) {
                if (pluginClass.isInstance(plugin)) {
                    pluginList.add(plugin);
                }
            }
            return pluginList;
        }
    }


    /**
     * Stops a plugin by plugin name and repository.
     *
     * @param pluginName the name of the plugin to stop.
     * @return Plugin the plugin, if stopped, or null if the
     *         the plugin was not found in the registry.
     */
    public Plugin stopPlugin(final String pluginName) {
        synchronized (pluginMap) {
            Plugin plugin = pluginMap.get(pluginName);

            if (plugin == null) {
                return null;
            }

            // shutdown the plugin
            plugin.shutdown();

            // remove it from the plugin map
            pluginMap.remove(pluginName);
            firePluginStopped(plugin);

            // return it for future use
            return plugin;
        }
    }

    /**
     * Stops all plugins in the given logger repository.
     */
    public void stopAllPlugins() {
        synchronized (pluginMap) {
            // remove the listener for this repository
            loggerRepository.removeLoggerRepositoryEventListener(listener);

            for (Object o : pluginMap.values()) {
                Plugin plugin = (Plugin) o;
                plugin.shutdown();
                firePluginStopped(plugin);
            }
        }
    }


    /**
     * Adds a PluginListener to this registry to be notified
     * of PluginEvents.
     *
     * @param l PluginListener to add to this registry
     */
    public void addPluginListener(final PluginListener l) {
        listenerList.add(l);
    }


    /**
     * Removes a particular PluginListener from this registry
     * such that it will no longer be notified of PluginEvents.
     *
     * @param l PluginListener to remove
     */
    public void removePluginListener(final PluginListener l) {
        listenerList.remove(l);
    }

    /**
     * Internal class used to handle listener events from repositories.
     */
    private class RepositoryListener implements LoggerRepositoryEventListener {
        /**
         * Stops all plugins associated with the repository being reset.
         *
         * @param repository the repository that was reset.
         */
        public void configurationResetEvent(final LoggerRepository repository) {
            PluginRegistry.this.stopAllPlugins();
        }


        /**
         * Called when the repository configuration is changed.
         *
         * @param repository the repository that was changed.
         */
        public void configurationChangedEvent(
                final LoggerRepository repository) {
            // do nothing with this event
        }


        /**
         * Stops all plugins associated with the repository being shutdown.
         *
         * @param repository the repository being shutdown.
         */
        public void shutdownEvent(final LoggerRepository repository) {
            PluginRegistry.this.stopAllPlugins();
        }
    }
}
