/*******************************************************************************
 * Copyright (c) 2003, 2005 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.update.internal.configurator;

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

import org.eclipse.core.runtime.*;
import org.eclipse.osgi.framework.log.*;
import org.eclipse.osgi.service.datalocation.*;
import org.eclipse.osgi.service.debug.*;
import org.eclipse.osgi.util.NLS;
import org.eclipse.update.configurator.*;
import org.osgi.framework.*;
import org.osgi.service.packageadmin.*;
import org.osgi.service.startlevel.*;
import org.osgi.util.tracker.*;

public class ConfigurationActivator implements BundleActivator, IBundleGroupProvider, IConfigurationConstants {

	public static String PI_CONFIGURATOR = "org.eclipse.update.configurator"; //$NON-NLS-1$
	public static final String INSTALL_LOCATION = "osgi.installLocation"; //$NON-NLS-1$
	public static final String LAST_CONFIG_STAMP = "last.config.stamp"; //$NON-NLS-1$
	public static final String NAME_SPACE = "org.eclipse.update"; //$NON-NLS-1$
	public static final String UPDATE_PREFIX = "update@"; //$NON-NLS-1$
	private static final String INITIAL_PREFIX = "initial@"; //$NON-NLS-1$
	
	// debug options
	public static String OPTION_DEBUG = PI_CONFIGURATOR + "/debug"; //$NON-NLS-1$
	// debug values
	public static boolean DEBUG = false;
	// os
	private static boolean isWindows = System.getProperty("os.name").startsWith("Win"); //$NON-NLS-1$ //$NON-NLS-2$
	
	private static BundleContext context;
	private ServiceTracker platformTracker;
	private ServiceRegistration configurationFactorySR;
	private PlatformConfiguration configuration;
	
	// Install location
	private static URL installURL;
	
	// Location of the configuration data
	private Location configLocation;
	
	//Need to store that because it is not provided by the platformConfiguration
	private long lastTimeStamp;

	// The expected states timestamp
	private long lastStateTimeStamp;
	
	// Singleton
	private static ConfigurationActivator configurator;

	public ConfigurationActivator() {
		configurator = this;
	}
	
	public void start(BundleContext ctx) throws Exception {
		context = ctx;
		loadOptions();
		acquireFrameworkLogService();
		initialize();
		
		//Short cut, if the configuration has not changed
		if (canRunWithCachedData()) {		
			Utils.debug("Running with cached data"); //$NON-NLS-1$
			Platform.registerBundleGroupProvider(this);
			return;
		}

		Utils.debug("Starting update configurator..."); //$NON-NLS-1$

		installBundles();
		Platform.registerBundleGroupProvider(this);
	}


	private void initialize() throws Exception {
		// TODO this test is not really needed any more than any plugin has 
		// to test to see if the runtime is running.  It was there from earlier days
		// where startup was much more disjoint.  Some day that level of decoupling
		// will return but for now...
		if (!Platform.isRunning())
			throw new Exception(Messages.ConfigurationActivator_initialize); 
		
		configLocation = Platform.getConfigurationLocation();
		// create the name space directory for update (configuration/org.eclipse.update)
		if (!configLocation.isReadOnly()) {
			try {
				URL privateURL = new URL(configLocation.getURL(), NAME_SPACE);
				File f = new File(privateURL.getFile());
				if(!f.exists())
					f.mkdirs();
			} catch (MalformedURLException e1) {
				// ignore
			}
		}
		configurationFactorySR = context.registerService(IPlatformConfigurationFactory.class.getName(), new PlatformConfigurationFactory(), null);
		configuration = getPlatformConfiguration(getInstallURL(), configLocation);
		if (configuration == null)
			throw Utils.newCoreException(NLS.bind(Messages.ConfigurationActivator_createConfig, (new String[] { configLocation.getURL().toExternalForm() })), null);

		DataInputStream stream = null;
		try {
			stream = new DataInputStream(new URL(configLocation.getURL(),NAME_SPACE+'/'+LAST_CONFIG_STAMP).openStream());
			lastTimeStamp = stream.readLong();
			lastStateTimeStamp = stream.readLong();
		} catch (Exception e) {
			lastTimeStamp = configuration.getChangeStamp() - 1;
			lastStateTimeStamp = -1;
		} finally {
			if (stream != null)
				try {
					stream.close();
				} catch (IOException e1) {
					Utils.log(e1.getLocalizedMessage());
				}
		}
	}


	public void stop(BundleContext ctx) throws Exception {
		// quick fix (hack) for bug 47861
		try {
			PlatformConfiguration.shutdown();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		configurationFactorySR.unregister();
	}

	public boolean installBundles() {
		Utils.debug("Installing bundles..."); //$NON-NLS-1$
		ServiceReference reference = context.getServiceReference(StartLevel.class.getName());
		int startLevel = 4;
		String defaultStartLevel = System.getProperty("osgi.bundles.defaultStartLevel"); //$NON-NLS-1$
		if (defaultStartLevel != null) {
			try {
				startLevel = Integer.parseInt(defaultStartLevel);
			} catch (NumberFormatException e1) {
				startLevel = 4;
			}
		}
		if (startLevel < 1)
			startLevel = 4;
		
		StartLevel start = null;
		if (reference != null)
			start = (StartLevel) context.getService(reference);
		try {
			// Get the list of cached bundles and compare with the ones to be installed.
			// Uninstall all the cached bundles that do not appear on the new list
			Bundle[] cachedBundles = context.getBundles();		
			URL[] plugins = configuration.getPluginPath();
				
			// starts the list of bundles to refresh with all currently unresolved bundles (see bug 50680)
			List toRefresh = getUnresolvedBundles();

			Bundle[] bundlesToUninstall = getBundlesToUninstall(cachedBundles, plugins);
			for (int i=0; i<bundlesToUninstall.length; i++) {
				try {
					if (DEBUG)
						Utils.debug("Uninstalling " + bundlesToUninstall[i].getLocation()); //$NON-NLS-1$
					// include every bundle being uninstalled in the list of bundles to refresh (see bug 82393)					
					toRefresh.add(bundlesToUninstall[i]);					
					bundlesToUninstall[i].uninstall();
				} catch (Exception e) {
					Utils.log(NLS.bind(Messages.ConfigurationActivator_uninstallBundle, (new String[] { bundlesToUninstall[i].getLocation() })));
				}
			}
			
			// Get the urls to install
			String[] bundlesToInstall = getBundlesToInstall(cachedBundles, plugins);

			for (int i = 0; i < bundlesToInstall.length; i++) {
				try {
					if (DEBUG)
						Utils.debug("Installing " + bundlesToInstall[i]); //$NON-NLS-1$
					URL bundleURL = new URL("reference:file:"+bundlesToInstall[i]); //$NON-NLS-1$
					//Bundle target = context.installBundle(bundlesToInstall[i]);
					Bundle target = context.installBundle(UPDATE_PREFIX+bundlesToInstall[i], bundleURL.openStream());
					// any new bundle should be refreshed as well
					toRefresh.add(target);
					if (start != null)
						start.setBundleStartLevel(target, startLevel);
				
				} catch (Exception e) {
					if (!Utils.isAutomaticallyStartedBundle(bundlesToInstall[i]))
						Utils.log(NLS.bind(Messages.ConfigurationActivator_installBundle, (new String[] { bundlesToInstall[i] })) + "   " + e.getMessage()); //$NON-NLS-1$
				}
			}
			context.ungetService(reference);
			removeInitialBundles(toRefresh, cachedBundles);
			refreshPackages((Bundle[]) toRefresh.toArray(new Bundle[toRefresh.size()]));
			
			// keep track of the last config successfully processed
			writePlatformConfigurationTimeStamp();
			return true;
		} catch (Exception e) {
			return false;
		} 
	}

	private void removeInitialBundles(List bundles, Bundle[] cachedBundles) {
		String[] initialSymbolicNames = getInitialSymbolicNames(cachedBundles);
		Iterator iter = bundles.iterator();
		while(iter.hasNext()) {
			Bundle bundle = (Bundle) iter.next();
			String symbolicName = bundle.getSymbolicName();
			for(int i = 0; i < initialSymbolicNames.length; i++) {
				if (initialSymbolicNames[i].equals(symbolicName)) {
					iter.remove();
					break;
				}
			}
		}
	}

	private String[] getInitialSymbolicNames(Bundle[] cachedBundles) {
		ArrayList initial = new ArrayList();
		for (int i = 0; i < cachedBundles.length; i++) {
			Bundle bundle = cachedBundles[i];
			if (bundle.getLocation().startsWith(INITIAL_PREFIX)) {
				String symbolicName = bundle.getSymbolicName();
				if (symbolicName != null)
					initial.add(symbolicName);
			}
		}
		return (String[]) initial.toArray(new String[initial.size()]);
	}

	private List getUnresolvedBundles() {
		Bundle[] allBundles = context.getBundles();
		List unresolved = new ArrayList(); 
		for (int i = 0; i < allBundles.length; i++)
			if (allBundles[i].getState() == Bundle.INSTALLED)
				unresolved.add(allBundles[i]);
		return unresolved;
	}

	private String[] getBundlesToInstall(Bundle[] cachedBundles, URL[] newPlugins) {
		// First, create a map of the cached bundles, for faster lookup
		HashSet cachedBundlesSet = new HashSet(cachedBundles.length);
		int offset = UPDATE_PREFIX.length();
		for (int i=0; i<cachedBundles.length; i++) {
			if (cachedBundles[i].getBundleId() == 0)
				continue; // skip the system bundle
			String bundleLocation = cachedBundles[i].getLocation();
			// Ignore bundles not installed by us
			if (!bundleLocation.startsWith(UPDATE_PREFIX))
				continue;
			
			bundleLocation = bundleLocation.substring(offset);
			cachedBundlesSet.add(bundleLocation);
			// On windows, we will be doing case insensitive search as well, so lower it now
			if (isWindows)
				cachedBundlesSet.add(bundleLocation.toLowerCase());
		}
		
		ArrayList bundlesToInstall = new ArrayList(newPlugins.length);
		for (int i = 0; i < newPlugins.length; i++) {
			String location = makeRelative(getInstallURL(), newPlugins[i]).getFile();
			// check if already installed
			if (cachedBundlesSet.contains(location))
				continue;
			if (isWindows && cachedBundlesSet.contains(location.toLowerCase()))
				continue;
			
			bundlesToInstall.add(location);
		}
		return (String[])bundlesToInstall.toArray(new String[bundlesToInstall.size()]);	
	}
	
	
	private Bundle[] getBundlesToUninstall(Bundle[] cachedBundles, URL[] newPlugins) {
		// First, create a map for faster lookups
		HashSet newPluginsSet = new HashSet(newPlugins.length);
		for (int i=0; i<newPlugins.length; i++) {
			
			String pluginLocation = makeRelative(getInstallURL(), newPlugins[i]).getFile();
			newPluginsSet.add(pluginLocation);
			// On windows, we will be doing case insensitive search as well, so lower it now
			if (isWindows)
				newPluginsSet.add(pluginLocation.toLowerCase());
		}
		
		ArrayList bundlesToUninstall = new ArrayList();
		int offset = UPDATE_PREFIX.length();
		for (int i=0; i<cachedBundles.length; i++) {
			if (cachedBundles[i].getBundleId() == 0)
				continue; // skip the system bundle
			String cachedBundleLocation = cachedBundles[i].getLocation();
			// Only worry about bundles we installed
			if (!cachedBundleLocation.startsWith(UPDATE_PREFIX))
				continue;
			cachedBundleLocation = cachedBundleLocation.substring(offset);

			if (newPluginsSet.contains(cachedBundleLocation))
				continue;
			if (isWindows && newPluginsSet.contains(cachedBundleLocation.toLowerCase()))
				continue;
			
			bundlesToUninstall.add(cachedBundles[i]);
		}
		return (Bundle[])bundlesToUninstall.toArray(new Bundle[bundlesToUninstall.size()]);
	}
	

	/**
	 * Creates and starts the platform configuration.
	 * @return the just started platform configuration
	 */
	private PlatformConfiguration getPlatformConfiguration(URL installURL, Location configLocation) {
		try {
			PlatformConfiguration.startup(installURL, configLocation);
		} catch (Exception e) {
			if (platformTracker != null) {
				String message = e.getMessage();
				if (message == null)
					message = ""; //$NON-NLS-1$
				Utils.log(Utils.newStatus(message, e));
			}
		}
		return PlatformConfiguration.getCurrent();

	}

	/**
	 * Do PackageAdmin.refreshPackages() in a synchronous way.  After installing
	 * all the requested bundles we need to do a refresh and want to ensure that 
	 * everything is done before returning.
	 * @param bundles
	 */
	private void refreshPackages(Bundle[] bundles) {
		if (bundles.length == 0)
			return;
		ServiceReference packageAdminRef = context.getServiceReference(PackageAdmin.class.getName());
		PackageAdmin packageAdmin = null;
		if (packageAdminRef != null) {
			packageAdmin = (PackageAdmin) context.getService(packageAdminRef);
			if (packageAdmin == null)
				return;
		}
		// TODO this is such a hack it is silly.  There are still cases for race conditions etc
		// but this should allow for some progress...
		// (patch from John A.)
		final boolean[] flag = new boolean[] {false};
		FrameworkListener listener = new FrameworkListener() {
			public void frameworkEvent(FrameworkEvent event) {
				if (event.getType() == FrameworkEvent.PACKAGES_REFRESHED)
					synchronized (flag) {
						flag[0] = true;
						flag.notifyAll();
					}
			}
		};
		context.addFrameworkListener(listener);
		packageAdmin.refreshPackages(bundles);
		synchronized (flag) {
			while (!flag[0]) {
				try {
					flag.wait();
				} catch (InterruptedException e) {
				}
			}
		}
		context.removeFrameworkListener(listener);
		context.ungetService(packageAdminRef);
	}
	
	private void writePlatformConfigurationTimeStamp() {
		DataOutputStream stream = null;
		try {
			if (configLocation.isReadOnly())
				return;
			
			String configArea = configLocation.getURL().getFile();
			lastTimeStamp = configuration.getChangeStamp();
			lastStateTimeStamp = Platform.getPlatformAdmin().getState(false).getTimeStamp();
			stream = new DataOutputStream(new FileOutputStream(configArea +File.separator+ NAME_SPACE+ File.separator+ LAST_CONFIG_STAMP));
			stream.writeLong(lastTimeStamp);
			stream.writeLong(lastStateTimeStamp);
		} catch (Exception e) {
			Utils.log(e.getLocalizedMessage());
		} finally {
			if (stream != null)
				try {
					stream.close();
				} catch (IOException e1) {
					Utils.log(e1.getLocalizedMessage());
				}
		}
	}

	private void loadOptions() {
		// all this is only to get the application args		
		DebugOptions service = null;
		ServiceReference reference = context.getServiceReference(DebugOptions.class.getName());
		if (reference != null)
			service = (DebugOptions) context.getService(reference);
		if (service == null)
			return;
		try {
			DEBUG = service.getBooleanOption(OPTION_DEBUG, false);
		} finally {
			// we have what we want - release the service
			context.ungetService(reference);
		}
	}
	
	private boolean canRunWithCachedData() {
		return  !"true".equals(System.getProperty("osgi.checkConfiguration")) && //$NON-NLS-1$ //$NON-NLS-2$
				lastTimeStamp==configuration.getChangeStamp() &&
				lastStateTimeStamp==Platform.getPlatformAdmin().getState(false).getTimeStamp();
	}
				
	public static BundleContext getBundleContext() {
		return context;
	}
		
	public static URL getInstallURL() {
		if (installURL == null)
			installURL = Platform.getInstallLocation().getURL();
		return installURL;
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.core.runtime.IBundleGroupProvider#getName()
	 */
	public String getName() {
		return Messages.BundleGroupProvider; 
	}
	/* (non-Javadoc)
	 * @see org.eclipse.core.runtime.IBundleGroupProvider#getBundleGroups()
	 */
	public IBundleGroup[] getBundleGroups() {
		if (configuration == null)
			return new IBundleGroup[0];
		else {
			IPlatformConfiguration.IFeatureEntry[] features = configuration.getConfiguredFeatureEntries();
			ArrayList bundleGroups = new ArrayList(features.length);
			for (int i=0; i<features.length; i++) {
				if (features[i] instanceof FeatureEntry 
					&& ((FeatureEntry)features[i]).hasBranding())
					bundleGroups.add(features[i]);
			}
			return (IBundleGroup[])bundleGroups.toArray(new IBundleGroup[bundleGroups.size()]);
		}
	}

	public static void setConfigurator(ConfigurationActivator configurator) {
		ConfigurationActivator.configurator = configurator;
	}

	public static ConfigurationActivator getConfigurator() {
		return configurator;
	}
	
	private void acquireFrameworkLogService() throws Exception{
		ServiceReference logServiceReference = context.getServiceReference(FrameworkLog.class.getName());
		if (logServiceReference == null)
			return;
		Utils.log  = (FrameworkLog) context.getService(logServiceReference);
	}
	
	/**
	 * Returns a URL which is equivalent to the given URL relative to the
	 * specified base URL. Works only for file: URLs
	 */
	public URL makeRelative(URL base, URL location) {
		if (base == null)
			return location;
		if (!"file".equals(base.getProtocol())) //$NON-NLS-1$
			return location;
		if (!base.getProtocol().equals(location.getProtocol()))
			return location;
		if (base.getHost() == null ^ location.getHost() == null)
			return location;
		if (base.getHost() != null && !base.getHost().equals(location.getHost()))
			return location;
		if (base.getPort() != location.getPort())
			return location;
		IPath locationPath = new Path(location.getPath());
		if (!locationPath.isAbsolute())
			return location;
		IPath relativePath = makeRelative(new Path(base.getPath()), locationPath);
		try {
			return new URL(base.getProtocol(), base.getHost(), base.getPort(), relativePath.toString());
		} catch (MalformedURLException e) {			
			String message = e.getMessage();
			if (message == null)
				message = ""; //$NON-NLS-1$
			Utils.log(Utils.newStatus(message, e));
		}
		return location;
	}
	
	/**
	 * Returns a path which is equivalent to the given location relative to the
	 * specified base path.
	 */
	public static IPath makeRelative(IPath base, IPath location) {
		if (location.getDevice() != null && !location.getDevice().equalsIgnoreCase(base.getDevice()))
			return location;
		int baseCount = base.segmentCount();
		int count = base.matchingFirstSegments(location);
		String temp = ""; //$NON-NLS-1$
		for (int j = 0; j < baseCount - count; j++)
			temp += "../"; //$NON-NLS-1$
		return new Path(temp).append(location.removeFirstSegments(count));
	}	
}
