/*
 * 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;

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.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);
    }
  }
}

