/*******************************************************************************
 * Copyright (c) 2000, 2003 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.update.internal.core;

import java.io.*;
import java.net.*;

import org.eclipse.core.runtime.*;
import org.eclipse.update.core.*;

public class InstallHandlerProxy implements IInstallHandler {

	private IFeature feature = null;
	private int type;
	private IInstallHandler handler = null;
	private IStatus savedStatus = null;
	private boolean DEBUG = false;

	private static final String EXT_PLUGIN = "org.eclipse.update.core";
	private static final String EXT_POINT = "installHandlers";

	private InstallHandlerProxy() {
	}

	public InstallHandlerProxy(
		int type,
		IFeature feature,
		IInstallHandlerEntry entry,
		InstallMonitor monitor)
		throws CoreException {

		initialize(type, feature, entry, monitor);
	}

	/*
	 * @see IInstallHandler#initialize
	 */
	public void initialize(
		int type,
		IFeature feature,
		IInstallHandlerEntry entry,
		InstallMonitor monitor)
		throws CoreException {

		DEBUG = UpdateCore.DEBUG_SHOW_IHANDLER;
		// validate arguments
		if (feature == null)
			throw new IllegalArgumentException();
		this.feature = feature;
		this.type = type;

		//  check if we have a handler entry specified in the feature.xml
		if (entry == null) {
			if (DEBUG)
				debug("not specified");
			return; // no handler entry
		}

		String library = entry.getLibrary();
		String handlerName = entry.getHandlerName();
		if (handlerName == null || handlerName.trim().equals("")) {
			if (DEBUG)
				debug("not specified");
			return; // no handler class spacified in entry
		}
		if (DEBUG) {
			debug("handler=" + handlerName);
			debug("path=   " + library);
		}

		// get handler instance
		try {
			if (library == null || library.trim().equals(""))
				this.handler = getGlobalHandler(handlerName);
			else
				this.handler = getLocalHandler(library, handlerName);
			if (this.handler == null)
				return;
			handler.initialize(type, feature, entry, monitor);
		} catch (ClassNotFoundException e) {
			handleExceptionInInit(
				Policy.bind("InstallHandler.notFound", feature.getLabel()),
				e);
			//$NON-NLS-1$
		} catch (ClassCastException e) {
			handleExceptionInInit(
				Policy.bind("InstallHandler.invalidHandler", feature.getLabel()),
				e);
			//$NON-NLS-1$
		} catch (CoreException e) {
			handleExceptionInInit(null, e);
		} catch (Exception e) {
			handleExceptionInInit(
				Policy.bind("InstallHandler.unableToCreateHandler", feature.getLabel()),
				e);
			//$NON-NLS-1$
		}

	}

	/*
	 * @see IInstallHandler#installInitiated
	 */
	public void installInitiated() throws CoreException {
		if (handler == null)
			return;
		else {
			try {
				if (DEBUG)
					debug("calling installInitiated()");
				handler.installInitiated();
			} catch (Throwable e) {
				handleExceptionInCall(e, feature);
			}
		}
	}

	/*
	 * @see IInstallHandler#allPluginsDownloaded
	 */
	public void pluginsDownloaded(IPluginEntry[] plugins) throws CoreException {
		if (handler == null)
			return;
		else {
			try {
				if (DEBUG)
					debug("calling pluginsDownloaded()");
				handler.pluginsDownloaded(plugins);
			} catch (Throwable e) {
				handleExceptionInCall(e, feature);
			}
		}
	}

	/*
	 * @see IInstallHandler#allPluginsInstalled
	 */
	public void completeInstall(IFeatureContentConsumer consumer)
		throws CoreException {
		if (handler == null)
			return;
		else {
			try {
				if (DEBUG)
					debug("calling completeInstall()");
				handler.completeInstall(consumer);
			} catch (Throwable e) {
				handleExceptionInCall(e, feature);
			}
		}
	}

	/*
	 * @see IInstallHandler#allDataDownloaded
	 */
	public void nonPluginDataDownloaded(
		INonPluginEntry[] nonPluginData,
		IVerificationListener listener)
		throws CoreException {
		if (handler == null)
			return;
		else {
			try {
				if (DEBUG)
					debug("calling nonPluginDataDownloaded()");
				handler.nonPluginDataDownloaded(nonPluginData, listener);
			} catch (Throwable e) {
				handleExceptionInCall(e, feature);
			}
		}
	}

	/*
	 * @see IInstallHandler#installCompleted
	 */
	public void installCompleted(boolean success) throws CoreException {
		if (handler == null)
			return;
		else {
			try {
				if (DEBUG)
					debug("calling installCompleted()");
				handler.installCompleted(success);
			} catch (Throwable e) {
				handleExceptionInCall(e, feature);
			}
		}
	}

	/*
	 * @see IInstallHandler#configureInitiated
	 */
	public void configureInitiated() throws CoreException {
		if (handler == null)
			return;
		else {
			try {
				if (DEBUG)
					debug("calling configureInitiated()");
				handler.configureInitiated();
			} catch (Throwable e) {
				handleExceptionInCall(e, feature);
			}
		}
	}

	/*
	 * @see IInstallHandler#completeConfigure
	 */
	public void completeConfigure() throws CoreException {
		if (handler == null)
			return;
		else {
			try {
				if (DEBUG)
					debug("calling completeConfigure()");
				handler.completeConfigure();
			} catch (Throwable e) {
				handleExceptionInCall(e, feature);
			}
		}
	}

	/*
	 * @see IInstallHandler#configureCompleted
	 */
	public void configureCompleted(boolean success) throws CoreException {
		if (handler == null)
			return;
		else {
			try {
				if (DEBUG)
					debug("calling configureCompleted()");
				handler.configureCompleted(success);
			} catch (Throwable e) {
				handleExceptionInCall(e, feature);
			}
		}
	}

	/*
	 * @see IInstallHandler#unconfigureInitiated
	 */
	public void unconfigureInitiated() throws CoreException {
		if (handler == null)
			return;
		else {
			try {
				if (DEBUG)
					debug("calling unconfigureInitiated()");
				handler.unconfigureInitiated();
			} catch (Throwable e) {
				handleExceptionInCall(e, feature);
			}
		}
	}

	/*
	 * @see IInstallHandler#completeUnconfigure
	 */
	public void completeUnconfigure() throws CoreException {
		if (handler == null)
			return;
		else {
			try {
				if (DEBUG)
					debug("calling completeUnconfigure()");
				handler.completeUnconfigure();
			} catch (Throwable e) {
				handleExceptionInCall(e, feature);
			}
		}
	}

	/*
	 * @see IInstallHandler#unconfigureCompleted
	 */
	public void unconfigureCompleted(boolean success) throws CoreException {
		if (handler == null) {
			if (savedStatus == null)
				return;
			else
				throw new CoreException(savedStatus); // delayed exception
		} else {
			try {
				if (DEBUG)
					debug("calling unconfigureCompleted()");
				handler.unconfigureCompleted(success);
			} catch (Throwable e) {
				handleExceptionInCall(e, feature);
			}
			if (savedStatus != null)
				throw new CoreException(savedStatus); // delayed exception
		}
	}

	/*
	 * @see IInstallHandler#uninstallInitiated
	 */
	public void uninstallInitiated() throws CoreException {
		if (handler == null)
			return;
		else {
			try {
				if (DEBUG)
					debug("calling uninstallInitiated()");
				handler.uninstallInitiated();
			} catch (Throwable e) {
				handleExceptionInCall(e, feature);
			}
		}
	}

	/*
	 * @see IInstallHandler#completeUninstall
	 */
	public void completeUninstall() throws CoreException {
		if (handler == null)
			return;
		else {
			try {
				if (DEBUG)
					debug("calling completeUninstall()");
				handler.completeUninstall();
			} catch (Throwable e) {
				handleExceptionInCall(e, feature);
			}
		}
	}

	/*
	 * @see IInstallHandler#uninstallCompleted
	 */
	public void uninstallCompleted(boolean success) throws CoreException {
		if (handler == null) {
			if (savedStatus == null)
				return;
			else
				throw new CoreException(savedStatus); // delayed exception
		} else {
			try {
				if (DEBUG)
					debug("calling uninstallCompleted()");
				handler.uninstallCompleted(success);
			} catch (Throwable e) {
				handleExceptionInCall(e, feature);
			}
			if (savedStatus != null)
				throw new CoreException(savedStatus); // delayed exception
		}
	}

	/*
	 * common exception handling for initialization
	 */
	private void handleExceptionInInit(String s, Exception e)
		throws CoreException {

		CoreException ce;
		if (e instanceof CoreException)
			ce = (CoreException) e;
		else
			ce = Utilities.newCoreException(s, e);

		if (isUndoAction()) {
			// for "undo" operations, deactivate handler and log error
			String id =
				UpdateCore.getPlugin().getDescriptor().getUniqueIdentifier();
			IStatus status =
				new Status(IStatus.ERROR, id, 0, "InstallHandler.deactivated", ce);
			//$NON-NLS-1$
			UpdateCore.getPlugin().getLog().log(status);
			handler = null; // disable subsequent handler calls
			savedStatus = status;
		} else
			// for "do" operations, hurl ...
			throw ce;
	}

	/*
	 * common exception handling for calls to install handler
	 */
	private void handleExceptionInCall(Throwable e, IFeature feature)
		throws CoreException {

		CoreException ce;
		if (e instanceof CoreException)
			ce = (CoreException) e;
		else
			ce =
				Utilities.newCoreException(
					Policy.bind("InstallHandler.callException", feature.getLabel()),
					e);
		//$NON-NLS-1$
		
		if (isUndoAction()) {
			// for "undo" operations, deactivate handler and log error
			String id =
				UpdateCore.getPlugin().getDescriptor().getUniqueIdentifier();
			IStatus status =
				new Status(IStatus.ERROR, id, 0, "InstallHandler.deactivated", ce);
			//$NON-NLS-1$
			UpdateCore.getPlugin().getLog().log(status);
			handler = null; // disable subsequent handler calls
			savedStatus = status;
		} else
			// for "do" operations, hurl ...
			throw ce;
	}

	/*
	 * Indicates whether we are doing (install, configure) or 
	 * undoing (uninstall, unconfigure)
	 */
	private boolean isUndoAction() {
		if (this.type == IInstallHandler.HANDLER_ACTION_INSTALL
			|| this.type == IInstallHandler.HANDLER_ACTION_CONFIGURE)
			return false; // causes exception to be thrown and action aborted
		else
			return true; // causes exception to be logged and action continues
	}

	/*
	 * get an instance of handler downloaded as part of the feature
	 */
	private IInstallHandler getLocalHandler(String lib, String name)
		throws Exception {

		// Get baseline URL for handler (relative to feature.xml). For
		// features being installed from a server (eg. http protocol)
		// the URL will most likely be to a local file copy containing the
		// unpacked feature jar.
		ContentReference baseRef =
			feature.getFeatureContentProvider().getFeatureManifestReference(null);
		URL base = null;
		if (baseRef != null)
			base = baseRef.asURL();
		if (base == null)
			throw Utilities.newCoreException(
				Policy.bind("InstallHandler.unableToCreateHandler", this.feature.getLabel()),
				null);
		//$NON-NLS-1$

		// determine loader class path
		URL cp = new URL(base, lib);
		if (this.type == IInstallHandler.HANDLER_ACTION_UNINSTALL) {
			// check if we are doing uninstall
			// ... need to make temp copy of library (being removed)
			File tempLib = File.createTempFile("tmp", ".jar");
			tempLib.deleteOnExit();
			FileOutputStream fos = null;
			InputStream is = null;
			try {
				fos = new FileOutputStream(tempLib);
				is = UpdateCore.getPlugin().get(cp).getInputStream();
				Utilities.copy(is, fos, null);
			} finally {
				if (fos != null)
					try {
						fos.close();
					} catch (Exception e) {
					}
				if (is != null)
					try {
						is.close();
					} catch (Exception e) {
					}
			}
			cp = tempLib.toURL();
		}

		// create class loader, load and instantiate handler
		URLClassLoader loader =
			new URLClassLoader(new URL[] { cp }, this.getClass().getClassLoader());
		Class clazz = loader.loadClass(name);
		IInstallHandler handler = (IInstallHandler) clazz.newInstance();
		return handler;
	}

	/*
	 * get instance of global handler registered via extension point
	 */
	private IInstallHandler getGlobalHandler(String name) throws Exception {

		IPluginRegistry reg = Platform.getPluginRegistry();
		IConfigurationElement[] handlerExtension =
			reg.getConfigurationElementsFor(EXT_PLUGIN, EXT_POINT, name);
		if (handlerExtension == null || handlerExtension.length <= 0)
			throw Utilities.newCoreException(
				Policy.bind("InstallHandler.unableToCreateHandler", this.feature.getLabel()),
				null);
		//$NON-NLS-1$	

		return (IInstallHandler) handlerExtension[0].createExecutableExtension("class");
	}
	
	private void debug(String s) {
		String pfx = (feature==null) ? "" : feature.getVersionedIdentifier().toString();
		System.out.println("InstallHandler["+pfx+"]: " + s);
	}
}
