/*
 * 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.geode.internal;

import static java.util.stream.Collectors.joining;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Proxy;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import org.apache.geode.annotations.VisibleForTesting;
import org.apache.geode.annotations.internal.MakeNotStatic;
import org.apache.geode.distributed.internal.DistributionConfig;
import org.apache.geode.internal.util.CollectionUtils;

/**
 * The delegating <tt>ClassLoader</tt> used by GemFire to load classes and other resources. This
 * <tt>ClassLoader</tt> delegates to any <tt>ClassLoader</tt>s added to the list of custom class
 * loaders, thread context <tt>ClassLoader</tt> s unless they have been excluded}, the
 * <tt>ClassLoader</tt> which loaded the GemFire classes, and finally the system
 * <tt>ClassLoader</tt>.
 *
 * <p>
 * The thread context class loaders can be excluded by setting the system property
 * <tt>gemfire.excludeThreadContextClassLoader</tt>:
 * <ul>
 * <li><tt>-Dgemfire.excludeThreadContextClassLoader=true</tt>
 * <li><tt>System.setProperty("gemfire.excludeThreadContextClassLoader", "true");</tt>
 * </ul>
 *
 * <p>
 * Class loading and resource loading order:
 * <ul>
 * <li>1. Any custom loaders in the order they were added
 * <li>2. <tt>Thread.currentThread().getContextClassLoader()</tt> unless excludeTCCL == true
 * <li>3. <tt>ClassPathLoader.class.getClassLoader()</tt>
 * <li>4. <tt>ClassLoader.getSystemClassLoader()</tt> If the attempt to acquire any of the above
 * class loaders results in either a {@code SecurityException} or a null, then that class loader is
 * quietly skipped. Duplicate class loaders will be skipped.
 * </ul>
 *
 * <p>
 * See http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-5.html for more information about
 * {@code ClassLoader}s.
 *
 * @since GemFire 6.5.1.4
 */
public class ClassPathLoader {
  private static final Logger logger = LogManager.getLogger();

  static final String EXCLUDE_TCCL_PROPERTY =
      DistributionConfig.GEMFIRE_PREFIX + "excludeThreadContextClassLoader";

  @MakeNotStatic
  private static volatile ClassPathLoader latest;

  private final HashMap<String, DeployJarChildFirstClassLoader> latestJarNamesToClassLoader =
      new HashMap<>();

  private volatile DeployJarChildFirstClassLoader leafLoader;

  private final JarDeployer jarDeployer;

  private final boolean excludeTCCL;

  public ClassPathLoader(boolean excludeTCCL) {
    this.excludeTCCL = excludeTCCL;
    jarDeployer = new JarDeployer();
    rebuildClassLoaderForDeployedJars();
  }

  public ClassPathLoader(boolean excludeTCCL, File workingDir) {
    this.excludeTCCL = excludeTCCL;
    jarDeployer = new JarDeployer(workingDir);
    rebuildClassLoaderForDeployedJars();
  }

  @VisibleForTesting
  static ClassPathLoader setLatestToDefault() {
    latest = new ClassPathLoader(Boolean.getBoolean(EXCLUDE_TCCL_PROPERTY));
    return latest;
  }

  public static ClassPathLoader setLatestToDefault(File workingDir) {
    latest = new ClassPathLoader(Boolean.getBoolean(EXCLUDE_TCCL_PROPERTY), workingDir);
    return latest;
  }

  public JarDeployer getJarDeployer() {
    return jarDeployer;
  }

  /**
   * createWithDefaults is exposed for testing.
   */
  @VisibleForTesting
  static ClassPathLoader createWithDefaults(final boolean excludeTCCL) {
    return new ClassPathLoader(excludeTCCL);
  }

  private synchronized void rebuildClassLoaderForDeployedJars() {
    leafLoader = null;
    Collection<DeployedJar> deployedJars = jarDeployer.getDeployedJars().values();
    for (DeployedJar deployedJar : deployedJars) {
      chainClassloader(deployedJar);
    }
  }

  private ClassLoader getLeafLoader() {
    if (leafLoader == null) {
      return ClassPathLoader.class.getClassLoader();
    }
    return leafLoader;
  }

  synchronized void chainClassloader(DeployedJar jar) {
    leafLoader = new DeployJarChildFirstClassLoader(latestJarNamesToClassLoader,
        new URL[] {jar.getFileURL()}, jar.getJarName(), getLeafLoader());
  }

  synchronized void unloadClassloaderForJar(String jarName) {
    latestJarNamesToClassLoader.put(jarName, null);
  }

  public URL getResource(final String name) {
    final boolean isTraceEnabled = logger.isTraceEnabled();
    if (isTraceEnabled) {
      logger.trace("getResource({})", name);
    }

    for (ClassLoader classLoader : getClassLoaders()) {
      if (isTraceEnabled) {
        logger.trace("getResource trying: {}", classLoader);
      }
      try {
        URL url = classLoader.getResource(name);

        if (url != null) {
          if (isTraceEnabled) {
            logger.trace("getResource found by: {}", classLoader);
          }
          return url;
        }
      } catch (SecurityException e) {
        // try next classLoader
      }
    }

    return null;
  }

  public Class<?> forName(final String name) throws ClassNotFoundException {
    final boolean isTraceEnabled = logger.isTraceEnabled();
    if (isTraceEnabled) {
      logger.trace("forName({})", name);
    }

    Class<?> clazz = forName(name, isTraceEnabled);
    if (clazz != null)
      return clazz;

    throw new ClassNotFoundException(name);
  }

  private Class<?> forName(String name, boolean isTraceEnabled) {
    for (ClassLoader classLoader : getClassLoaders()) {
      if (isTraceEnabled) {
        logger.trace("forName trying: {}", classLoader);
      }
      try {
        // Do not look up class definitions in jars that have been unloaded or are old
        if (classLoader instanceof DeployJarChildFirstClassLoader) {
          if (((DeployJarChildFirstClassLoader) classLoader).thisIsOld()) {
            return null;
          }
        }
        Class<?> clazz = Class.forName(name, true, classLoader);
        if (clazz != null) {
          if (isTraceEnabled) {
            logger.trace("forName found by: {}", classLoader);
          }
          return clazz;
        }
      } catch (SecurityException | ClassNotFoundException e) {
        // try next classLoader
      }
    }
    return null;
  }

  /**
   * See {@link Proxy#getProxyClass(ClassLoader, Class...)}
   */
  Class<?> getProxyClass(final Class<?>... classObjs) {
    IllegalArgumentException ex = null;

    for (ClassLoader classLoader : getClassLoaders()) {
      try {
        return Proxy.getProxyClass(classLoader, classObjs);
      } catch (SecurityException sex) {
        // Continue to next classloader
      } catch (IllegalArgumentException iaex) {
        ex = iaex;
        // Continue to next classloader
      }
    }

    if (ex != null) {
      throw ex;
    }
    return null;
  }

  @Override
  public String toString() {
    final StringBuilder sb = new StringBuilder(getClass().getName());
    sb.append("@").append(System.identityHashCode(this)).append("{");
    sb.append(", excludeTCCL=").append(excludeTCCL);
    sb.append(", classLoaders=[");
    sb.append(getClassLoaders().stream().map(ClassLoader::toString).collect(joining(", ")));
    sb.append("]}");
    return sb.toString();
  }

  /**
   * Finds the resource with the given name. This method will first search the class loader of the
   * context class for the resource. That failing, this method will invoke
   * {@link #getResource(String)} to find the resource.
   *
   * @param contextClass The class whose class loader will first be searched
   * @param name The resource name
   * @return A <tt>URL</tt> object for reading the resource, or <tt>null</tt> if the resource could
   *         not be found or the invoker doesn't have adequate privileges to get the resource.
   */
  public URL getResource(final Class<?> contextClass, final String name) {
    if (contextClass != null) {
      URL url = contextClass.getResource(name);
      if (url != null) {
        return url;
      }
    }
    return getResource(name);
  }

  /**
   * Returns an input stream for reading the specified resource.
   * <p>
   * The search order is described in the documentation for {@link #getResource(String)}.
   *
   * @param name The resource name
   * @return An input stream for reading the resource, or <tt>null</tt> if the resource could not be
   *         found
   */
  public InputStream getResourceAsStream(final String name) {
    URL url = getResource(name);
    try {
      return url != null ? url.openStream() : null;
    } catch (IOException e) {
      return null;
    }
  }

  /**
   * Returns an input stream for reading the specified resource.
   * <p>
   * The search order is described in the documentation for {@link #getResource(Class, String)}.
   *
   * @param contextClass The class whose class loader will first be searched
   * @param name The resource name
   * @return An input stream for reading the resource, or <tt>null</tt> if the resource could not be
   *         found
   */
  public InputStream getResourceAsStream(final Class<?> contextClass, final String name) {
    if (contextClass != null) {
      InputStream is = contextClass.getResourceAsStream(name);
      if (is != null) {
        return is;
      }
    }
    return getResourceAsStream(name);
  }

  /**
   * Finds all the resources with the given name. This method will first search the class loader of
   * the context class for the resource before searching all other {@code ClassLoader}s.
   *
   * @param contextClass The class whose class loader will first be searched
   * @param name The resource name
   * @return An enumeration of <tt>URL</tt> objects for the resource. If no resources could be
   *         found, the enumeration will be empty. Resources that the class loader doesn't have
   *         access to will not be in the enumeration.
   * @throws IOException If I/O errors occur
   * @see ClassLoader#getResources(String)
   */
  private Enumeration<URL> getResources(final Class<?> contextClass, final String name)
      throws IOException {
    final LinkedHashSet<URL> urls = new LinkedHashSet<>();

    if (contextClass != null) {
      CollectionUtils.addAll(urls, contextClass.getClassLoader().getResources(name));
    }

    for (ClassLoader classLoader : getClassLoaders()) {
      Enumeration<URL> resources = classLoader.getResources(name);
      if (resources != null && resources.hasMoreElements()) {
        CollectionUtils.addAll(urls, resources);
      }
    }

    return Collections.enumeration(urls);
  }

  public Enumeration<URL> getResources(final String name) throws IOException {
    return getResources(null, name);
  }

  private List<ClassLoader> getClassLoaders() {
    ArrayList<ClassLoader> classLoaders = new ArrayList<>();

    if (!excludeTCCL) {
      ClassLoader tccl = Thread.currentThread().getContextClassLoader();
      if (tccl != null) {
        classLoaders.add(tccl);
      }
    }

    classLoaders.add(getLeafLoader());
    return classLoaders;
  }

  /**
   * Wrap this {@code ClassPathLoader} with a {@code ClassLoader} facade.
   *
   * @return a ClassLoader facade.
   * @since GemFire 8.1
   */
  public ClassLoader asClassLoader() {
    return new ClassLoader() {
      @Override
      public Class<?> loadClass(String name) throws ClassNotFoundException {
        return forName(name);
      }

      @Override
      protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
        return forName(name);
      }

      @Override
      public URL getResource(String name) {
        return ClassPathLoader.this.getResource(name);
      }

      @Override
      public Enumeration<URL> getResources(String name) throws IOException {
        return ClassPathLoader.this.getResources(name);
      }

      @Override
      public InputStream getResourceAsStream(String name) {
        return ClassPathLoader.this.getResourceAsStream(name);
      }
    };
  }

  public static ClassPathLoader getLatest() {
    if (latest == null) {
      synchronized (ClassPathLoader.class) {
        if (latest == null)
          setLatestToDefault();
      }
    }

    return latest;
  }

  /**
   * Helper method equivalent to {@code ClassPathLoader.getLatest().asClassLoader();}.
   *
   * @return a ClassLoader for current ClassPathLoader.
   * @since GemFire 8.1
   */
  public static ClassLoader getLatestAsClassLoader() {
    return getLatest().asClassLoader();
  }

}
