/*
 * 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.openejb.util.classloader;

import org.apache.openejb.core.ParentClassLoaderFinder;
import org.apache.openejb.loader.SystemInstance;
import org.apache.openejb.util.JavaSecurityManagers;

import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;

// TODO: look SM usage, find a better name
public class URLClassLoaderFirst extends URLClassLoader {

    // log4j is optional, moreover it will likely not work if not skipped and loaded by a temp classloader
    private static final boolean SKIP_LOG4J = "true".equals(SystemInstance.get().getProperty("openejb.skip.log4j", "true")) && skipLib("org.apache.log4j.Logger");
    private static final boolean SKIP_MYFACES = "true".equals(SystemInstance.get().getProperty("openejb.skip.myfaces", "true")) && skipLib("org.apache.myfaces.spi.FactoryFinderProvider");
    private static final boolean SKIP_HSQLDB = skipLib("org.hsqldb.lib.HsqlTimer");
    // commons-net is only in tomee-plus
    private static final boolean SKIP_COMMONS_NET = skipLib("org.apache.commons.net.pop3.POP3Client");

    // first skip container APIs if not in the jaxrs or plus version
    private static final boolean SKIP_JAXWS = skipLib("org.apache.cxf.jaxws.support.JaxWsImplementorInfo");
    private static final boolean SKIP_JMS = skipLib("org.apache.activemq.broker.BrokerFactory");
    private static final boolean EMBEDDED = "true".equals(SystemInstance.get().getProperty("openejb.embedded"));

    // - will not match anything, that's the desired default behavior
    public static final Collection<String> FORCED_SKIP = new ArrayList<>();
    public static final Collection<String> FORCED_LOAD = new ArrayList<>();
    public static final Collection<String> FILTERABLE_RESOURCES = new ArrayList<>();

    static {
        reloadConfig();
        ClassLoader.registerAsParallelCapable();
    }

    public static final String SLF4J_BINDER_CLASS = "org/slf4j/impl/StaticLoggerBinder.class";
    private static final URL SLF4J_CONTAINER = URLClassLoaderFirst.class.getClassLoader().getResource(SLF4J_BINDER_CLASS);
    private static final String CLASS_EXT = ".class";
    public static final ClassLoader SYSTEM_CLASS_LOADER = ClassLoader.getSystemClassLoader();
    private static final boolean ALLOW_OPEN_EJB_SYSTEM_LOADING = !Boolean.getBoolean("openejb.classloader.first.disallow-system-loading");

    public static void reloadConfig() {
        list(FORCED_SKIP, "openejb.classloader.forced-skip", null);
        list(FORCED_LOAD, "openejb.classloader.forced-load", null);
        list(FILTERABLE_RESOURCES, "openejb.classloader.filterable-resources",
                "META-INF/services/javax.validation.spi.ValidationProvider," +
                "META-INF/services/javax.ws.rs.client.ClientBuilder," +
                "META-INF/services/javax.json.spi.JsonProvider," +
                "META-INF/services/javax.cache.spi.CachingProvider," +
                "META-INF/javamail.default.providers,META-INF/javamail.default.address.map," +
                "META-INF/javamail.charset.map,META-INF/mailcap," +
                SLF4J_BINDER_CLASS);
    }

    private static void list(final Collection<String> list, final String key, final String def) {
        list.clear();

        final String s = SystemInstance.get().getOptions().get(key, def);
        if (s != null && !s.trim().isEmpty()) {
            list.addAll(Arrays.asList(s.trim().split(",")));
        }
    }

    private static boolean skipLib(final String includedClass) {
        try {
            URLClassLoaderFirst.class.getClassLoader().loadClass(includedClass);
            return "true".equalsIgnoreCase(JavaSecurityManagers.getSystemProperty(includedClass + ".skip", "true"));
        } catch (final ClassNotFoundException e) {
            return false;
        }
    }

    private final ClassLoader system;

    public URLClassLoaderFirst(final URL[] urls, final ClassLoader parent) {
        super(urls, parent);
        system = ClassLoader.getSystemClassLoader();
    }

    @Override
    public Class<?> loadClass(final String name, final boolean resolve) throws ClassNotFoundException {
        synchronized (getClassLoadingLock(name)) {
            // already loaded?
            Class<?> clazz = findLoadedClass(name);
            if (clazz != null) {
                if (resolve) {
                    resolveClass(clazz);
                }
                return clazz;
            }

            // JSE classes?
            if (canBeLoadedFromSystem(name)) {
                try {
                    clazz = system.loadClass(name);
                    if (clazz != null) {
                        if (resolve) {
                            resolveClass(clazz);
                        }
                        return clazz;
                    }
                } catch (final NoClassDefFoundError | ClassNotFoundException ignored) {
                    // no-op
                }
            }

            // look for it in this classloader
            final boolean ok = !(shouldSkip(name) || shouldDelegateToTheContainer(this, name));
            if (ok) {
                clazz = loadInternal(name, resolve);
                if (clazz != null) {
                    return clazz;
                }
            }

            // finally delegate
            clazz = loadFromParent(name, resolve);
            if (clazz != null) {
                return clazz;
            }

            if (!ok) {
                clazz = loadInternal(name, resolve);
                if (clazz != null) {
                    return clazz;
                }
            }

            throw new ClassNotFoundException(name);
        }
    }

    public static boolean shouldDelegateToTheContainer(final ClassLoader loader, final String name) {
        return shouldSkipJsf(loader, name) || shouldSkipSlf4j(loader, name);
    }

    private Class<?> loadFromParent(final String name, final boolean resolve) {
        ClassLoader parent = getParent();
        if (parent == null) {
            parent = system;
        }
        try {
            final Class<?> clazz = Class.forName(name, false, parent);
            if (clazz != null) {
                if (resolve) {
                    resolveClass(clazz);
                }
                return clazz;
            }
        } catch (final ClassNotFoundException ignored) {
            // no-op
        }
        return null;
    }

    public Class<?> findAlreadyLoadedClass(final String name) {
        return super.findLoadedClass(name);
    }

    public Class<?> loadInternal(final String name, final boolean resolve) {
        try {
            final Class<?> clazz = findClass(name);
            if (clazz != null) {
                if (resolve) {
                    resolveClass(clazz);
                }
                return clazz;
            }
        } catch (final ClassNotFoundException ignored) {
            // no-op
        }
        return null;
    }

    // we skip webapp enrichment jars since we want to load them from the webapp or lib
    // Note: this is not a real limitation since it is first fail it will be done later
    public static boolean canBeLoadedFromSystem(final String name) {
        return ALLOW_OPEN_EJB_SYSTEM_LOADING && (!name.startsWith("org.apache.openejb.") || !isWebAppEnrichment(name.substring("org.apache.openejb.".length())));
    }

    // making all these call inline if far more costly than factorizing packages
    //
    // /!\ please check org.apache.openejb.persistence.PersistenceUnitInfoImpl.isServerClass() too
    // when updating this method
    public static boolean shouldSkip(final String input) {

        String name = input;

        if (name == null) { // can happen with rest servlet definition or errors
            return false;
        }

        for (final String prefix : FORCED_SKIP) {
            if (name.startsWith(prefix)) {
                return true;
            }
        }
        for (final String prefix : FORCED_LOAD) {
            if (name.startsWith(prefix)) {
                return false;
            }
        }

        if (name.startsWith("openejb.shade.")) {
            name = name.substring("openejb.shade.".length());
        }

        if (name.startsWith("java.")) {
            return true;
        }
        if (name.startsWith("javax.faces.")) {
            return false;
        }
        if (name.startsWith("javax.mail.")) {
            return false;
        }
        if (name.startsWith("javax.") || name.startsWith("jakarta.")) {
            return isInServer(name);
        }
        if (name.startsWith("sun.")) {
            return isInJvm(name);
        }

        // can be provided in the webapp
        if (name.startsWith("javax.servlet.jsp.jstl")) {
            return false;
        }

        if (name.startsWith("org.")) {
            final String org = name.substring("org.".length());

            if (org.startsWith("apache.")) {
                final String apache = org.substring("apache.".length());

                // the following block is classes which enrich webapp classloader
                if (apache.startsWith("webbeans.jsf")) {
                    return false;
                }
                if (apache.startsWith("tomee.mojarra.")) {
                    return false;
                }

                // here we find server classes
                if (apache.startsWith("bval.")) {
                    return true;
                }
                if (apache.startsWith("openjpa.")) {
                    return true;
                }
                if (apache.startsWith("xbean.")) {
                    return !apache.substring("xbean.".length()).startsWith("spring");
                }
                if (apache.startsWith("geronimo.")) {
                    return true;
                }
                if (apache.startsWith("coyote.")) {
                    return true;
                }
                if (apache.startsWith("webbeans.")) {
                    return true;
                }
                if (apache.startsWith("log4j.") && SKIP_LOG4J) {
                    return true;
                }
                if (apache.startsWith("catalina.")) {
                    return true;
                }
                if (apache.startsWith("jasper.")) {
                    return true;
                }
                if (apache.startsWith("tomcat.")) {
                    return true;
                }
                if (apache.startsWith("el.")) {
                    return true;
                }
                // if (apache.startsWith("jsp")) return true; // precompiled jsp have to be loaded from the webapp
                if (apache.startsWith("naming.")) {
                    return true;
                }
                if (apache.startsWith("taglibs.standard.")) {
                    return true;
                }

                if (apache.startsWith("openejb.")) { // skip all excepted webapp enrichment artifacts
                    return !isWebAppEnrichment(apache.substring("openejb.".length()));
                }

                if (apache.startsWith("commons.")) {
                    final String commons = apache.substring("commons.".length());

                    // don't stop on commons package since we don't bring all commons
                    if (commons.startsWith("beanutils.")) {
                        return isInServer(name);
                    }
                    if (commons.startsWith("cli.")) {
                        return true;
                    }
                    if (commons.startsWith("codec.")) {
                        return true;
                    }
                    if (commons.startsWith("collections.")) {
                        return true;
                    }
                    if (commons.startsWith("dbcp.")) {
                        return true;
                    }
                    if (commons.startsWith("dbcp2.")) {
                        return true;
                    }
                    if (commons.startsWith("digester.")) {
                        return true;
                    }
                    if (commons.startsWith("jocl.")) {
                        return true;
                    }
                    if (commons.startsWith("lang.")) { // openjpa
                        return true;
                    }
                    if (commons.startsWith("lang3.")) {  // us
                        return true;
                    }
                    if (commons.startsWith("logging.")) {
                        return false;
                    }
                    if (commons.startsWith("pool.")) {
                        return true;
                    }
                    if (commons.startsWith("pool2.")) {
                        return true;
                    }
                    if (commons.startsWith("net.") && SKIP_COMMONS_NET) {
                        return true;
                    }

                    return false;
                }

                if (SKIP_MYFACES && apache.startsWith("myfaces.")) {
                    // we bring only myfaces-impl (+api but that's javax)
                    // mainly inspired from a comparison with tomahawk packages
                    final String myfaces = name.substring("myfaces.".length());
                    if (myfaces.startsWith("shared.")) {
                        return true;
                    }
                    if (myfaces.startsWith("ee.")) {
                        return true;
                    }
                    if (myfaces.startsWith("lifecycle.")) {
                        return true;
                    }
                    if (myfaces.startsWith("context.")) {
                        return true;
                    }
                    if (myfaces.startsWith("logging.")) {
                        return true;
                    }
                    // tomahawk uses component.html package
                    if (myfaces.startsWith("component.visit.") || myfaces.equals("component.ComponentResourceContainer")) {
                        return true;
                    }
                    if (myfaces.startsWith("application.")) {
                        return true;
                    }
                    if (myfaces.startsWith("config.")) {
                        return true;
                    }
                    if (myfaces.startsWith("event.")) {
                        return true;
                    }

                    if (myfaces.startsWith("resource.")) {
                        return true;
                    }
                    if (myfaces.startsWith("el.")) {
                        return true;
                    }
                    if (myfaces.startsWith("spi.")) {
                        return true;
                    }
                    if (myfaces.startsWith("convert.")) {
                        return true;
                    }
                    if (myfaces.startsWith("debug.")) {
                        return true;
                    }
                    if (myfaces.startsWith("util.")) {
                        return true;
                    }
                    if (myfaces.startsWith("view.")) {
                        return true;
                    }
                    if (myfaces.equals("convert.ConverterUtils")) {
                        return true;
                    }

                    if (myfaces.startsWith("renderkit.")) {
                        final String renderkit = myfaces.substring("renderkit.".length());
                        if (renderkit.startsWith("html.Html")) {
                            return true;
                        }
                        final char firstNextletter = renderkit.charAt(0);
                        if (Character.isUpperCase(firstNextletter)) {
                            return true;
                        }
                        return false;
                    }

                    if (myfaces.startsWith("taglib.")) {
                        final String taglib = myfaces.substring("taglib.".length());
                        if (taglib.startsWith("html.Html")) {
                            return true;
                        }
                        if (taglib.startsWith("core.")) {
                            return true;
                        }
                        return false;
                    }

                    if (myfaces.startsWith("webapp.")) {
                        final String webapp = myfaces.substring("webapp.".length());
                        if (webapp.startsWith("Faces")) {
                            return true;
                        }
                        if (webapp.startsWith("Jsp")) {
                            return true;
                        }
                        if (webapp.startsWith("Startup")) {
                            return true;
                        }
                        if (webapp.equals("AbstractFacesInitializer")) {
                            return true;
                        }
                        if (webapp.equals("MyFacesServlet")) {
                            return true;
                        }
                        if (webapp.equals("ManagedBeanDestroyerListener")) {
                            return true;
                        }
                        if (webapp.equals("WebConfigParamsLogger")) {
                            return true;
                        }
                        return false;
                    }

                    return false;
                }

                if (apache.startsWith("activemq.")) {
                    return SKIP_JMS && isInServer(name);
                }

                return false;
            }

            // other org packages
            if (org.startsWith("hsqldb.") && SKIP_HSQLDB) {
                return true;
            }
            if (org.startsWith("codehaus.swizzle.")) {
                final String swizzle = org.substring("codehaus.swizzle.".length());
                if (swizzle.startsWith("stream.")) {
                    return true;
                }
                if (swizzle.startsWith("rss.")) {
                    return true;
                }
                if (swizzle.startsWith("Grep.class") || swizzle.startsWith("Lexer.class")) {
                    return true;
                }
                return false;
            }
            if (org.startsWith("w3c.dom.") || org.startsWith("xml.sax.")) {
                return isInJvm(name);
            }
            if (org.startsWith("eclipse.jdt.")) {
                return true;
            }

            // let an app use its own slf4j impl (so its own api too)
            // if (org.startsWith("slf4j")) return true;

            return false;
        }

        // other packages
        if (name.startsWith("com.")) {
            final String sub = name.substring("com.".length());
            if (sub.startsWith("sun.")) {
                return !name.startsWith("sun.mail.") && isInJvm(name);
            }
            if (sub.startsWith("oracle.")) {
                return true;
            }
        }
        if (name.startsWith("jdk.")) {
            return true;
        }

        if (name.startsWith("serp.bytecode.")) {
            return true;
        }

        return false;
    }

    private static boolean isInJvm(final String name) {
        return SYSTEM_CLASS_LOADER.getResource(name.replace('.', '/') + CLASS_EXT) != null;
    }

    private static boolean isInServer(final String name) {
        if (name.startsWith("javax.")) {
            final String sub = name.substring("javax.".length());
            if (sub.startsWith("jws.")) {
                return SKIP_JAXWS || EMBEDDED;
            }
            if (sub.startsWith("jms.")) {
                return SKIP_JMS || EMBEDDED;
            }
        }
        if (name.startsWith("jakarta.")) {
            final String sub = name.substring("jakarta.".length());
            if (sub.startsWith("jws.")) {
                return SKIP_JAXWS || EMBEDDED;
            }
            if (sub.startsWith("jms.")) {
                return SKIP_JMS || EMBEDDED;
            }
        }
        return ParentClassLoaderFinder.Helper.get().getResource(name.replace('.', '/') + ".class") != null;
    }

    public static boolean shouldSkipJsf(final ClassLoader loader, final String name) {
        if (!name.startsWith("javax.faces.")) {
            return false;
        }

        // using annotation to test to avoid to load more classes with deps
        final String testClass;
        // these test classes have to be jsf 2.x AND 1.x otherwise we force JSF 2
        if ("javax.faces.webapp.FacesServlet".equals(name)) {
            testClass = "javax.faces.FactoryFinder";
        } else {
            testClass = "javax.faces.webapp.FacesServlet";
        }

        final String classname = testClass.replace('.', '/') + ".class";
        try {
            final Enumeration<URL> resources = loader.getResources(classname);
            final Collection<URL> thisJSf = Collections.list(resources);
            return thisJSf.isEmpty() || thisJSf.size() <= 1;
        } catch (final IOException e) {
            return true;
        }

    }

    // in org.apache.openejb.
    private static boolean isWebAppEnrichment(final String openejb) {
        return openejb.startsWith("hibernate.") || openejb.startsWith("jpa.integration.")
            || openejb.startsWith("toplink.") || openejb.startsWith("eclipselink.")
            || openejb.startsWith("arquillian.");
    }

    @Override
    public Enumeration<URL> getResources(final String name) throws IOException {
        return URLClassLoaderFirst.filterResources(name, super.getResources(name));
    }

    public static boolean isFilterableResource(final String name) {
        // currently bean validation, Slf4j, myfaces (because of enrichment)
        return name != null
            && (FILTERABLE_RESOURCES.contains(name) || name.startsWith("META-INF/services/org.apache.myfaces.spi"));
    }

    public static boolean shouldSkipSlf4j(final ClassLoader loader, final String name) {
        if (name == null || !name.startsWith("org.slf4j.")) {
            return false;
        }

        try { // using getResource here just returns randomly the container one so we need getResources
            final Enumeration<URL> resources = loader.getResources(SLF4J_BINDER_CLASS);
            while (resources.hasMoreElements()) {
                final URL resource = resources.nextElement();
                if (!resource.equals(SLF4J_CONTAINER)) {
                    // applicative slf4j
                    return false;
                }
            }
        } catch (final Throwable e) {
            // no-op
        }

        return true;
    }

    // useful method for SPI
    public static Enumeration<URL> filterResources(final String name, final Enumeration<URL> result) {
        if (isFilterableResource(name)) {
            final Collection<URL> values = Collections.list(result);
            if (values.size() > 1) {
                // remove openejb one
                final URL url = URLClassLoaderFirst.class.getResource("/" + name);
                if (url != null) {
                    values.remove(url);
                }
            }
            return Collections.enumeration(values);
        }
        return result;
    }
}
