/*
 * 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.openjpa.lib.util;

import java.io.IOException;
import java.net.URL;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;

/**
 * Class loader type that can be configured to delegate to multiple
 * internal class loaders.
 * The {@link #THREAD_LOADER} constant is a marker that will be replaced
 * with the context loader of the current thread.
 *
 * @author Abe White
 */
public class MultiClassLoader extends ClassLoader {

    /**
     * Marker that will be replaced with the context loader of the current
     * thread whenever it is discovered in the class loader list.
     */
    public static final ClassLoader THREAD_LOADER = null;

    /**
     * The standard system class loader.
     */
    public static final ClassLoader SYSTEM_LOADER =
        AccessController.doPrivileged(
            J2DoPrivHelper.getSystemClassLoaderAction());

    private List<ClassLoader> _loaders = new ArrayList<>(5);

    /**
     * Constructor; initializes the loader with an empty list of delegates.
     */
    public MultiClassLoader() {
        super(null);
    }

    /**
     * Construct with the class loaders of another multi loader.
     */
    public MultiClassLoader(MultiClassLoader other) {
        super(null);
        addClassLoaders(other);
    }

    public MultiClassLoader(ClassLoader... loaders) {
        for (ClassLoader loader : loaders) {
            addClassLoader(loader);
        }
    }

    /**
     * Returns true if the list contains the given class loader or marker.
     */
    public boolean containsClassLoader(ClassLoader loader) {
        return _loaders.contains(loader);
    }

    /**
     * Return an array of all contained class loaders.
     */
    public ClassLoader[] getClassLoaders() {
        ClassLoader[] loaders = new ClassLoader[size()];
        ClassLoader loader;
        Iterator<ClassLoader> itr = _loaders.iterator();
        for (int i = 0; i < loaders.length; i++) {
            loader = itr.next();
            if (loader == THREAD_LOADER)
                loader = AccessController.doPrivileged(
                    J2DoPrivHelper.getContextClassLoaderAction());
            loaders[i] = loader;
        }
        return loaders;
    }

    /**
     * Return the class loader at the given index.
     */
    public ClassLoader getClassLoader(int index) {
        ClassLoader loader = (ClassLoader) _loaders.get(index);
        if (loader == THREAD_LOADER)
            loader = AccessController.doPrivileged(
                J2DoPrivHelper.getContextClassLoaderAction());
        return loader;
    }

    /**
     * Add the given class loader to the set of loaders that will be tried.
     *
     * @return true if the loader was added, false if already in the list
     */
    public boolean addClassLoader(ClassLoader loader) {
        if (_loaders.contains(loader))
            return false;
        return _loaders.add(loader);
    }

    /**
     * Add the given class loader at the specified index.
     *
     * @return true if the loader was added, false if already in the list
     */
    public boolean addClassLoader(int index, ClassLoader loader) {
        if (_loaders.contains(loader))
            return false;
        _loaders.add(index, loader);
        return true;
    }

    /**
     * Set the class loaders of this loader to those of the given loader.
     */
    public void setClassLoaders(MultiClassLoader multi) {
        clear();
        addClassLoaders(multi);
    }

    /**
     * Adds all class loaders from the given multi loader starting at the
     * given index.
     *
     * @return true if any loaders were added, false if all already in list
     */
    public boolean addClassLoaders(int index, MultiClassLoader multi) {
        if (multi == null)
            return false;

        // use iterator so that the thread loader is not resolved
        boolean added = false;
        for (Iterator<ClassLoader> itr = multi._loaders.iterator(); itr.hasNext();) {
            if (addClassLoader(index, (ClassLoader) itr.next())) {
                index++;
                added = true;
            }
        }
        return added;
    }

    /**
     * Adds all the class loaders from the given multi loader.
     *
     * @return true if any loaders were added, false if all already in list
     */
    public boolean addClassLoaders(MultiClassLoader multi) {
        if (multi == null)
            return false;

        // use iterator so that the thread loader is not resolved
        boolean added = false;
        for (Iterator<ClassLoader> itr = multi._loaders.iterator(); itr.hasNext();)
            added = addClassLoader((ClassLoader) itr.next()) || added;
        return added;
    }

    /**
     * Remove the given loader from the list.
     *
     * @return true if removed, false if not in list
     */
    public boolean removeClassLoader(ClassLoader loader) {
        return _loaders.remove(loader);
    }

    /**
     * Clear the list of class loaders.
     */
    public void clear() {
        _loaders.clear();
    }

    /**
     * Return the number of internal class loaders.
     */
    public int size() {
        return _loaders.size();
    }

    /**
     * Return true if there are no internal class laoders.
     */
    public boolean isEmpty() {
        return _loaders.isEmpty();
    }

    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        ClassLoader loader;
        for (Iterator<ClassLoader> itr = _loaders.iterator(); itr.hasNext();) {
            loader = (ClassLoader) itr.next();
            if (loader == THREAD_LOADER)
                loader = AccessController.doPrivileged(
                    J2DoPrivHelper.getContextClassLoaderAction());
            try {
                return Class.forName(name, false, loader);
            } catch (Throwable t) {
            }
        }
        throw new ClassNotFoundException(name);
    }

    @Override
    protected URL findResource(String name) {
        ClassLoader loader;
        URL rsrc;
        for (Iterator<ClassLoader> itr = _loaders.iterator(); itr.hasNext();) {
            loader = (ClassLoader) itr.next();
            if (loader == THREAD_LOADER)
                loader = AccessController.doPrivileged(
                    J2DoPrivHelper.getContextClassLoaderAction());

            if (loader == null) // skip
                continue;

            rsrc = AccessController.doPrivileged(
                J2DoPrivHelper.getResourceAction(loader, name));
            if (rsrc != null)
                return rsrc;
        }
        return null;
    }

    @Override
    protected Enumeration<URL> findResources(String name) throws IOException {
        ClassLoader loader;
        Enumeration<URL> rsrcs;
        URL rsrc;
        Vector<URL> all = new Vector<>();
        for (Iterator<ClassLoader> itr = _loaders.iterator(); itr.hasNext();) {
            loader = itr.next();
            if (loader == THREAD_LOADER)
                loader = AccessController.doPrivileged(
                    J2DoPrivHelper.getContextClassLoaderAction());

            if (loader == null) // skip
                continue;

            try {
                rsrcs = AccessController.doPrivileged(
                    J2DoPrivHelper.getResourcesAction(loader, name));
                while (rsrcs.hasMoreElements()) {
                    rsrc = rsrcs.nextElement();
                    if (!all.contains(rsrc))
                        all.addElement(rsrc);
                }
            } catch (PrivilegedActionException pae) {
                throw (IOException) pae.getException();
            }
        }
        return all.elements();
    }

    @Override
    public boolean equals(Object other) {
        if (other == this)
            return true;
        if (!(other instanceof MultiClassLoader))
            return false;
        return ((MultiClassLoader) other)._loaders.equals(_loaders);
    }

    @Override
    public int hashCode() {
        return _loaders.hashCode();
    }
}
