/*******************************************************************************
 * Copyright (c) 2005, 2006 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/

package org.eclipse.core.runtime.internal.adaptor;

import java.io.*;
import java.net.URLConnection;
import java.util.*;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.SAXParserFactory;
import org.eclipse.core.runtime.adaptor.LocationManager;
import org.eclipse.osgi.baseadaptor.*;
import org.eclipse.osgi.baseadaptor.hooks.AdaptorHook;
import org.eclipse.osgi.framework.adaptor.FrameworkAdaptor;
import org.eclipse.osgi.framework.console.CommandProvider;
import org.eclipse.osgi.framework.debug.Debug;
import org.eclipse.osgi.framework.debug.FrameworkDebugOptions;
import org.eclipse.osgi.framework.internal.core.Constants;
import org.eclipse.osgi.framework.log.FrameworkLog;
import org.eclipse.osgi.framework.log.FrameworkLogEntry;
import org.eclipse.osgi.internal.baseadaptor.AdaptorUtil;
import org.eclipse.osgi.service.datalocation.Location;
import org.eclipse.osgi.service.pluginconversion.PluginConverter;
import org.eclipse.osgi.service.resolver.PlatformAdmin;
import org.eclipse.osgi.service.runnable.ApplicationLauncher;
import org.eclipse.osgi.service.urlconversion.URLConverter;
import org.osgi.framework.*;

public class EclipseAdaptorHook implements AdaptorHook, HookConfigurator {
	/** The SAX factory name */
	public static final String SAXFACTORYNAME = "javax.xml.parsers.SAXParserFactory"; //$NON-NLS-1$
	/** The DOM factory name */
	public static final String DOMFACTORYNAME = "javax.xml.parsers.DocumentBuilderFactory"; //$NON-NLS-1$
	private static final String RUNTIME_ADAPTOR = FrameworkAdaptor.FRAMEWORK_SYMBOLICNAME + "/eclipseadaptor"; //$NON-NLS-1$
	private static final String OPTION_CONVERTER = RUNTIME_ADAPTOR + "/converter/debug"; //$NON-NLS-1$
	private static final String OPTION_LOCATION = RUNTIME_ADAPTOR + "/debug/location"; //$NON-NLS-1$

	private BaseAdaptor adaptor;
	private boolean noXML = false;

	public void frameworkStart(BundleContext context) throws BundleException {
		registerEndorsedXMLParser(context);
		Location location = LocationManager.getUserLocation();
		Hashtable locationProperties = new Hashtable(1);
		if (location != null) {
			locationProperties.put("type", LocationManager.PROP_USER_AREA); //$NON-NLS-1$
			context.registerService(Location.class.getName(), location, locationProperties);
		}
		location = LocationManager.getInstanceLocation();
		if (location != null) {
			locationProperties.put("type", LocationManager.PROP_INSTANCE_AREA); //$NON-NLS-1$
			context.registerService(Location.class.getName(), location, locationProperties);
		}
		location = LocationManager.getConfigurationLocation();
		if (location != null) {
			locationProperties.put("type", LocationManager.PROP_CONFIG_AREA); //$NON-NLS-1$
			context.registerService(Location.class.getName(), location, locationProperties);
		}
		location = LocationManager.getInstallLocation();
		if (location != null) {
			locationProperties.put("type", LocationManager.PROP_INSTALL_AREA); //$NON-NLS-1$
			context.registerService(Location.class.getName(), location, locationProperties);
		}

		Dictionary urlProperties = new Hashtable();
		urlProperties.put("protocol", new String[] {"bundleentry", "bundleresource"}); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
		context.registerService(URLConverter.class.getName(), new URLConverterImpl(), urlProperties);

		AdaptorUtil.register(org.eclipse.osgi.service.environment.EnvironmentInfo.class.getName(), EclipseEnvironmentInfo.getDefault(), context);
		AdaptorUtil.register(PlatformAdmin.class.getName(), adaptor.getPlatformAdmin(), context);
		PluginConverter converter = PluginConverterImpl.getDefault();
		if (converter == null)
			converter = new PluginConverterImpl(adaptor, context);
		AdaptorUtil.register(PluginConverter.class.getName(), converter, context);
		AdaptorUtil.register(CommandProvider.class.getName(), new EclipseCommandProvider(context), context);
		AdaptorUtil.register(org.eclipse.osgi.service.localization.BundleLocalization.class.getName(), new BundleLocalizationImpl(), context);
	}

	private void registerEndorsedXMLParser(BundleContext bc) {
		try {
			Class.forName(SAXFACTORYNAME);
			bc.registerService(SAXFACTORYNAME, new SaxParsingService(), new Hashtable());
			Class.forName(DOMFACTORYNAME);
			bc.registerService(DOMFACTORYNAME, new DomParsingService(), new Hashtable());
		} catch (ClassNotFoundException e) {
			noXML = true;
			if (Debug.DEBUG && Debug.DEBUG_ENABLED) {
				String message = EclipseAdaptorMsg.ECLIPSE_ADAPTOR_ERROR_XML_SERVICE;
				adaptor.getFrameworkLog().log(new FrameworkLogEntry(FrameworkAdaptor.FRAMEWORK_SYMBOLICNAME, FrameworkLogEntry.ERROR, 0, message, 0, e, null));
			}
		}
	}

	private class SaxParsingService implements ServiceFactory {
		public Object getService(Bundle bundle, ServiceRegistration registration) {
			return SAXParserFactory.newInstance();
		}

		public void ungetService(Bundle bundle, ServiceRegistration registration, Object service) {
			// Do nothing.
		}
	}

	private class DomParsingService implements ServiceFactory {
		public Object getService(Bundle bundle, ServiceRegistration registration) {
			return DocumentBuilderFactory.newInstance();
		}

		public void ungetService(Bundle bundle, ServiceRegistration registration, Object service) {
			// Do nothing.
		}
	}

	public void frameworkStop(BundleContext context) throws BundleException {
		// TODO should unregister the services here
		printStats();
		if (!noXML)
			PluginParser.releaseXMLParsing();
	}

	private void printStats() {
		FrameworkDebugOptions debugOptions = FrameworkDebugOptions.getDefault();
		if (debugOptions == null)
			return;
		String registryParsing = debugOptions.getOption("org.eclipse.core.runtime/registry/parsing/timing/value"); //$NON-NLS-1$
		if (registryParsing != null)
			MessageHelper.debug("Time spent in registry parsing: " + registryParsing); //$NON-NLS-1$
		String packageAdminResolution = debugOptions.getOption("debug.packageadmin/timing/value"); //$NON-NLS-1$
		if (packageAdminResolution != null)
			System.out.println("Time spent in package admin resolve: " + packageAdminResolution); //$NON-NLS-1$			
		String constraintResolution = debugOptions.getOption("org.eclipse.core.runtime.adaptor/resolver/timing/value"); //$NON-NLS-1$
		if (constraintResolution != null)
			System.out.println("Time spent resolving the dependency system: " + constraintResolution); //$NON-NLS-1$ 
	}

	public void frameworkStopping(BundleContext context) {
		// Shutdown the ApplicationLauncher service if it is available.
		ServiceReference launcherRef = context.getServiceReference(ApplicationLauncher.class.getName());
		if (launcherRef != null) {
			ApplicationLauncher launcher = (ApplicationLauncher) context.getService(launcherRef);
			// this will force a currently running application to stop.
			launcher.shutdown();
			context.ungetService(launcherRef);
		}
	}

	public void addProperties(Properties properties) {
		// default to not verify EE at install time
		if (properties.getProperty(Constants.ECLIPSE_EE_INSTALL_VERIFY) == null)
			properties.put(Constants.ECLIPSE_EE_INSTALL_VERIFY, "false"); //$NON-NLS-1$
		// default to enable compatibility boot delegation
		if (properties.getProperty(Constants.OSGI_COMPATIBILITY_BOOTDELEGATION) == null)
			properties.put(Constants.OSGI_COMPATIBILITY_BOOTDELEGATION, "true"); //$NON-NLS-1$
	}

	public URLConnection mapLocationToURLConnection(String location) throws IOException {
		// do nothing
		return null;
	}

	public void handleRuntimeError(Throwable error) {
		// do nothing
	}

	public boolean matchDNChain(String pattern, String[] dnChain) {
		// do nothing
		return false;
	}

	public FrameworkLog createFrameworkLog() {
		// do nothing
		return null;
	}

	public void initialize(BaseAdaptor adaptor) {
		this.adaptor = adaptor;
		// EnvironmentInfo has to be initialized first to compute defaults for system context (see bug 88925)
		EclipseEnvironmentInfo.getDefault();
		setDebugOptions();
	}

	private void setDebugOptions() {
		FrameworkDebugOptions options = FrameworkDebugOptions.getDefault();
		// may be null if debugging is not enabled
		if (options == null)
			return;
		PluginConverterImpl.DEBUG = options.getBooleanOption(OPTION_CONVERTER, false);
		BasicLocation.DEBUG = options.getBooleanOption(OPTION_LOCATION, false);
	}

	public void addHooks(HookRegistry hookRegistry) {
		hookRegistry.addAdaptorHook(this);
	}

}
