/*
 * Copyright (C) 2007 Google Inc.
 *
 * Licensed 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 com.google.inject.internal.util;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * A reference queue with an associated background thread that dequeues
 * references and invokes {@link FinalizableReference#finalizeReferent()} on
 * them.
 *
 * <p>Keep a strong reference to this object until all of the associated
 * referents have been finalized. If this object is garbage collected earlier,
 * the backing thread will not invoke {@code finalizeReferent()} on the
 * remaining references.
 *
 * @author Bob Lee
 */
public class FinalizableReferenceQueue {

  /*
   * The Finalizer thread keeps a phantom reference to this object. When the
   * client (ReferenceMap, for example) no longer has a strong reference to
   * this object, the garbage collector will reclaim it and enqueue the
   * phantom reference. The enqueued reference will trigger the Finalizer to
   * stop.
   *
   * If this library is loaded in the system class loader,
   * FinalizableReferenceQueue can load Finalizer directly with no problems.
   *
   * If this library is loaded in an application class loader, it's important
   * that Finalizer not have a strong reference back to the class loader.
   * Otherwise, you could have a graph like this:
   *
   * Finalizer Thread
   *   runs instance of -> Finalizer.class
   *     loaded by -> Application class loader
   *       which loaded -> ReferenceMap.class
   *         which has a static -> FinalizableReferenceQueue instance
   *
   * Even if no other references to classes from the application class loader
   * remain, the Finalizer thread keeps an indirect strong reference to the
   * queue in ReferenceMap, which keeps the Finalizer running, and as a result,
   * the application class loader can never be reclaimed.
   *
   * This means that dynamically loaded web applications and OSGi bundles can't
   * be unloaded.
   *
   * If the library is loaded in an application class loader, we try to break
   * the cycle by loading Finalizer in its own independent class loader:
   *
   * System class loader
   *   -> Application class loader
   *     -> ReferenceMap
   *     -> FinalizableReferenceQueue
   *     -> etc.
   *   -> Decoupled class loader
   *     -> Finalizer
   *
   * Now, Finalizer no longer keeps an indirect strong reference to the
   * static FinalizableReferenceQueue field in ReferenceMap. The application
   * class loader can be reclaimed at which point the Finalizer thread will
   * stop and its decoupled class loader can also be reclaimed.
   *
   * If any of this fails along the way, we fall back to loading Finalizer
   * directly in the application class loader.
   */

  private static final Logger logger
      = Logger.getLogger(FinalizableReferenceQueue.class.getName());

  private static final String FINALIZER_CLASS_NAME
      = "com.google.inject.internal.util.Finalizer";

  /** Reference to Finalizer.startFinalizer(). */
  private static final Method startFinalizer;
  static {
    Class<?> finalizer = loadFinalizer(
        new SystemLoader(), new DecoupledLoader(), new DirectLoader());
    startFinalizer = getStartFinalizer(finalizer);
  }

  /**
   * The actual reference queue that our background thread will poll.
   */
  final ReferenceQueue<Object> queue;

  /**
   * Whether or not the background thread started successfully.
   */
  final boolean threadStarted;

  /**
   * Constructs a new queue.
   */
  @SuppressWarnings("unchecked")
  public FinalizableReferenceQueue() {
    // We could start the finalizer lazily, but I'd rather it blow up early.
    ReferenceQueue<Object> queue;
    boolean threadStarted = false;
    try {
      queue = (ReferenceQueue<Object>) startFinalizer.invoke(null,
          FinalizableReference.class, this);
      threadStarted = true;
    } catch (IllegalAccessException e) {
      // Finalizer.startFinalizer() is public.
      throw new AssertionError(e);
    } catch (Throwable t) {
      logger.log(Level.INFO, "Failed to start reference finalizer thread."
          + " Reference cleanup will only occur when new references are"
          + " created.", t);
      queue = new ReferenceQueue<Object>();
    }

    this.queue = queue;
    this.threadStarted = threadStarted;
  }

  /**
   * Repeatedly dequeues references from the queue and invokes
   * {@link FinalizableReference#finalizeReferent()} on them until the queue
   * is empty. This method is a no-op if the background thread was created
   * successfully.
   */
  void cleanUp() {
    if (threadStarted) {
      return;
    }

    Reference<?> reference;
    while ((reference = queue.poll()) != null) {
      /*
       * This is for the benefit of phantom references. Weak and soft
       * references will have already been cleared by this point.
       */
      reference.clear();
      try {
        ((FinalizableReference) reference).finalizeReferent();
      } catch (Throwable t) {
        logger.log(Level.SEVERE, "Error cleaning up after reference.", t);
      }
    }
  }

  /**
   * Iterates through the given loaders until it finds one that can load
   * Finalizer.
   *
   * @return Finalizer.class
   */
  private static Class<?> loadFinalizer(FinalizerLoader... loaders) {
    for (FinalizerLoader loader : loaders) {
      Class<?> finalizer = loader.loadFinalizer();
      if (finalizer != null) {
        return finalizer;
      }
    }

    throw new AssertionError();
  }

  /**
   * Loads Finalizer.class.
   */
  interface FinalizerLoader {

    /**
     * Returns Finalizer.class or null if this loader shouldn't or can't load
     * it.
     *
     * @throws SecurityException if we don't have the appropriate priveleges
     */
    Class<?> loadFinalizer();
  }

  /**
   * Tries to load Finalizer from the system class loader. If Finalizer is
   * in the system class path, we needn't create a separate loader.
   */
  static class SystemLoader implements FinalizerLoader {
    public Class<?> loadFinalizer() {
      ClassLoader systemLoader;
      try {
        systemLoader = ClassLoader.getSystemClassLoader();
      } catch (SecurityException e) {
        logger.info("Not allowed to access system class loader.");
        return null;
      }
      if (systemLoader != null) {
        try {
          return systemLoader.loadClass(FINALIZER_CLASS_NAME);
        } catch (ClassNotFoundException e) {
          // Ignore. Finalizer is simply in a child class loader.
          return null;
        }
      } else {
        return null;
      }
    }
  }

  /**
   * Try to load Finalizer in its own class loader. If Finalizer's thread
   * had a direct reference to our class loader (which could be that of
   * a dynamically loaded web application or OSGi bundle), it would prevent
   * our class loader from getting garbage collected.
   */
  static class DecoupledLoader implements FinalizerLoader {

    private static final String LOADING_ERROR = "Could not load Finalizer in"
        + " its own class loader. Loading Finalizer in the current class loader"
        + " instead. As a result, you will not be able to garbage collect this"
        + " class loader. To support reclaiming this class loader, either"
        + " resolve the underlying issue, or move Google Collections to your"
        + " system class path.";

    public Class<?> loadFinalizer() {
      try {
        /*
         * We use URLClassLoader because it's the only concrete class loader
         * implementation in the JDK. If we used our own ClassLoader subclass,
         * Finalizer would indirectly reference this class loader:
         *
         * Finalizer.class ->
         *   CustomClassLoader ->
         *     CustomClassLoader.class ->
         *       This class loader
         *
         * System class loader will (and must) be the parent.
         */
        ClassLoader finalizerLoader = newLoader(getBaseUrl());
        return finalizerLoader.loadClass(FINALIZER_CLASS_NAME);
      } catch (Exception e) {
        logger.log(Level.WARNING, LOADING_ERROR, e);
        return null;
      }
    }

    /**
     * Gets URL for base of path containing Finalizer.class.
     */
    URL getBaseUrl() throws IOException {
      // Find URL pointing to Finalizer.class file.
      String finalizerPath = FINALIZER_CLASS_NAME.replace('.', '/') + ".class";
      URL finalizerUrl = getClass().getClassLoader().getResource(finalizerPath);
      if (finalizerUrl == null) {
        throw new FileNotFoundException(finalizerPath);
      }

      // Find URL pointing to base of class path.
      String urlString = finalizerUrl.toString();
      if (!urlString.endsWith(finalizerPath)) {
        throw new IOException("Unsupported path style: " + urlString);
      }
      urlString = urlString.substring(0,
          urlString.length() - finalizerPath.length());
      return new URL(urlString);
    }

    /** Creates a class loader with the given base URL as its classpath. */
    URLClassLoader newLoader(URL base) {
      return new URLClassLoader(new URL[] { base });
    }
  }

  /**
   * Loads Finalizer directly using the current class loader. We won't be
   * able to garbage collect this class loader, but at least the world
   * doesn't end.
   */
  static class DirectLoader implements FinalizerLoader {
    public Class<?> loadFinalizer() {
      try {
        return Class.forName(FINALIZER_CLASS_NAME);
      } catch (ClassNotFoundException e) {
        throw new AssertionError(e);
      }
    }
  }

  /**
   * Looks up Finalizer.startFinalizer().
   */
  static Method getStartFinalizer(Class<?> finalizer) {
    try {
      return finalizer.getMethod("startFinalizer", Class.class, Object.class);
    } catch (NoSuchMethodException e) {
      throw new AssertionError(e);
    }
  }
}

