/*
 * 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.myfaces.extensions.scripting.core.common.util;


import org.apache.myfaces.extensions.scripting.core.api.WeavingContext;

import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * <p>Utility class for class loading purposes, e.g. to determine the classpath of a
 * class loader hierarchy.</p>
 */
public class ClassLoaderUtils {


    // ------------------------------------------ Public methods

    /**
     * CompilationResult
     * <p>Returns the default class loader to use.</p>
     *
     * @return the default class loader to use
     */
    public static ClassLoader getDefaultClassLoader() {
        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        if (classLoader != null) {
            return classLoader;
        } else {
            return ClassLoaderUtils.class.getClassLoader();
        }
    }

    /**
     * <p>Determines whether the given class is loadable by the given class loader.</p>
     *
     * @param className   the class you want to check
     * @param classLoader the class loader to use for that check
     * @return <code>true</code>, if the given class is loadable by the given class loader
     */
    public static boolean isClassAvailable(String className, ClassLoader classLoader) {
        try {
            classLoader.loadClass(className);
            return true;
        }
        catch (Throwable ex) {
            return false;
        }
    }

    /**
     * <p>Resolves the classpath by walking up the hierachy of class loaders. Assuming
     * that we're only dealing with URLClassLoaders it's possible to determine the
     * classpath. This method, however, returns the classpath as a String, where each
     * classpath entry is separated by a ';', i.e. it returns the classpath in a format
     * that Java tools usually expect it to be.</p>
     * <p/>
     * it also adds the additional classpaths issued by our configuration to the list
     *
     * @param classLoader the class loader which you want to resolve the class path for
     * @return the final classpath
     */
    public static String buildClasspath(ClassLoader classLoader) {
        StringBuilder classpath = new StringBuilder();

        URL[] urls = resolveClasspath(classLoader);
        for (URL url : urls) {
            classpath.append(url.getPath());

            // Note that the classpath separator character is platform
            // dependent. On Windows systems it's ";" whereas on other
            // UNIX systems it's ":".
            classpath.append(File.pathSeparatorChar);
        }

        String retVal = classpath.toString();
        if (retVal.endsWith(File.pathSeparator)) {
            retVal = retVal.substring(0, retVal.length() - 1);
        }
        return retVal;
    }

    /**
     * <p>Resolves the classpath by walking up the hierarchy of class loaders. Assuming
     * that we're only dealing with URLClassLoaders it's possible to determine the
     * classpath.</p>
     *
     * @param parent the class loader which you want to resolve the class path for
     * @return the final classpath
     */
    public static URL[] resolveClasspath(ClassLoader parent) {
        List<URL> classpath = new ArrayList<URL>();

        ClassLoader classLoader = parent;
        // Walk up the hierachy of class loaders in order to determine the current classpath.
        File target = WeavingContext.getInstance().getConfiguration().getCompileTarget();
        if (target != null) {
            addFile(classpath, target);
        }

        while (classLoader != null) {
            if (classLoader instanceof URLClassLoader) {
                URLClassLoader urlClassLoader = (URLClassLoader) classLoader;

                URL[] urls = urlClassLoader.getURLs();
                if (urls != null) {
                    classpath.addAll(Arrays.asList(urls));
                }
            } /*else {
                if (logger.isWarnEnabled()) {
                    logger.warn("Resolving the classpath of the classloader '" + parent + "' - One of its parent class"
                            + " loaders is no URLClassLoader '" + classLoader + "', which means it's possible that"
                            + " some classpath entries aren't in the final outcome of this method call.");
                }
            } */

            //we disable this warning entirely for now because our own url classloader
            //can deal with this properly, due to extra startup context classpath determination

            // Inspect the parent class loader next.
            classLoader = classLoader.getParent();
        }

        List<String> additionalClassPaths = WeavingContext.getInstance().getConfiguration().getAdditionalClassPath();
        if (!(additionalClassPaths == null || additionalClassPaths.isEmpty())) {
            for (String additionalClassPath : additionalClassPaths) {
                File additionalPath = new File(additionalClassPath);
                addFile(classpath, additionalPath);
            }
        }

        return classpath.toArray(new URL[classpath.size()]);
    }

    private static void addFile(List<URL> classpath, File additionalPath) {
        if (additionalPath.exists()) {
            try {
                classpath.add(additionalPath.toURI().toURL());
            } catch (MalformedURLException e) {
                Logger log = Logger.getLogger(ClassLoaderUtils.class.getName());
                log.log(Level.SEVERE, "Additionalclasspath wrong url", e);
            }
        }
    }

}
