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

import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.status.StatusLogger;
import org.apache.logging.log4j.util.Strings;

import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * Loads and manages all the plugins.
 */
public class PluginManager {

    private static final CopyOnWriteArrayList<String> PACKAGES = new CopyOnWriteArrayList<>();
    private static final String LOG4J_PACKAGES = "org.apache.logging.log4j.core";

    private static final Logger LOGGER = StatusLogger.getLogger();

    private Map<String, PluginType<?>> plugins = new HashMap<>();
    private final String category;

    /**
     * Constructs a PluginManager for the plugin category name given.
     * 
     * @param category The plugin category name.
     */
    public PluginManager(final String category) {
        this.category = category;
    }

    /**
     * Adds a package name to be scanned for plugins. Must be invoked prior to plugins being collected.
     * 
     * @param p The package name. Ignored if {@code null} or empty.
     */
    public static void addPackage(final String p) {
        if (Strings.isBlank(p)) {
            return;
        }
        PACKAGES.addIfAbsent(p);
    }

    /**
     * Adds a list of package names to be scanned for plugins. Convenience method for {@link #addPackage(String)}.
     *
     * @param packages collection of package names to add. Empty and null package names are ignored.
     */
    public static void addPackages(final Collection<String> packages) {
        for (final String pkg : packages) {
            if (Strings.isNotBlank(pkg)) {
                PACKAGES.addIfAbsent(pkg);
            }
        }
    }

    /**
     * Returns the type of a specified plugin.
     * 
     * @param name The name of the plugin.
     * @return The plugin's type.
     */
    public PluginType<?> getPluginType(final String name) {
        return plugins.get(name.toLowerCase());
    }

    /**
     * Returns all the matching plugins.
     * 
     * @return A Map containing the name of the plugin and its type.
     */
    public Map<String, PluginType<?>> getPlugins() {
        return plugins;
    }

    /**
     * Locates all the plugins.
     */
    public void collectPlugins() {
        collectPlugins(null);
    }

    /**
     * Locates all the plugins including search of specific packages. Warns about name collisions.
     *
     * @param packages the list of packages to scan for plugins
     * @since 2.1
     */
    public void collectPlugins(final List<String> packages) {
        final String categoryLowerCase = category.toLowerCase();
        final Map<String, PluginType<?>> newPlugins = new LinkedHashMap<>();

        // First, iterate the Log4j2Plugin.dat files found in the main CLASSPATH
        Map<String, List<PluginType<?>>> builtInPlugins = PluginRegistry.getInstance().loadFromMainClassLoader();
        if (builtInPlugins.isEmpty()) {
            // If we didn't find any plugins above, someone must have messed with the log4j-core.jar.
            // Search the standard package in the hopes we can find our core plugins.
            builtInPlugins = PluginRegistry.getInstance().loadFromPackage(LOG4J_PACKAGES);
        }
        mergeByName(newPlugins, builtInPlugins.get(categoryLowerCase));

        // Next, iterate any Log4j2Plugin.dat files from OSGi Bundles
        for (final Map<String, List<PluginType<?>>> pluginsByCategory : PluginRegistry.getInstance().getPluginsByCategoryByBundleId().values()) {
            mergeByName(newPlugins, pluginsByCategory.get(categoryLowerCase));
        }

        // Next iterate any packages passed to the static addPackage method.
        for (final String pkg : PACKAGES) {
            mergeByName(newPlugins, PluginRegistry.getInstance().loadFromPackage(pkg).get(categoryLowerCase));
        }
        // Finally iterate any packages provided in the configuration (note these can be changed at runtime).
        if (packages != null) {
            for (final String pkg : packages) {
                mergeByName(newPlugins, PluginRegistry.getInstance().loadFromPackage(pkg).get(categoryLowerCase));
            }
        }

        LOGGER.debug("PluginManager '{}' found {} plugins", category, newPlugins.size());

        plugins = newPlugins;
    }

    private static void mergeByName(final Map<String, PluginType<?>> newPlugins, final List<PluginType<?>> plugins) {
        if (plugins == null) {
            return;
        }
        for (final PluginType<?> pluginType : plugins) {
            final String key = pluginType.getKey();
            final PluginType<?> existing = newPlugins.get(key);
            if (existing == null) {
                newPlugins.put(key, pluginType);
            } else if (!existing.getPluginClass().equals(pluginType.getPluginClass())) {
                LOGGER.warn("Plugin [{}] is already mapped to {}, ignoring {}",
                    key, existing.getPluginClass(), pluginType.getPluginClass());
            }
        }
    }
}
