/*******************************************************************************
 * 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 java.util.*;

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

/**
 * Update manager reconciler application.
 * This application is invoked by the platform startup support
 * whenever changes are detected in the installation that require
 * the update state to be reconciled. Typically, this will be as
 * a result of installation actions that were done directly 
 * in the file system bypassing the Update Manager.
 * When triggered, this application performs the following:
 * <ul>
 * <li>call update manager reconciler
 * <li>if plugin path changed as a result of this call, trigger
 * restart ("exit code 23")
 * <li>if plugin path has not changed as a result of this call,
 * start this original application
 * </ul>
 */

public class UpdateManagerReconciler implements org.eclipse.core.runtime.IPlatformRunnable {

	// NOTE: originalApplication is set to a dummy string to prevent "silent"
	// failures in case of internal errors
	private String originalApplication = "org.eclipse.update.UNKNOWN"; //$NON-NLS-1$
	private boolean initialize = false;
	private boolean firstUse = false;
	private boolean optimistic = false;
	private boolean dumpfile = false;
	private boolean DEBUG = false;
	private String dumpFilename = "";

	private static final String RECONCILER_APP = "org.eclipse.update.core.reconciler";
	private static final String APPLICATION = "-application"; //$NON-NLS-1$	
	private static final String INITIALIZE = "-initialize"; //$NON-NLS-1$
	private static final String DUMPFILE = "-dumpfile"; //$NON-NLS-1$	
	private static final String FIRSTUSE = "-firstuse"; //$NON-NLS-1$
	private static final String CHANGES_MARKER = ".newupdates"; //$NON-NLS-1$

	/**
	 * @see IPlatformRunnable#run(Object)
	 */
	public Object run(Object args) throws Exception {

		// get debug setting and process command line arguments
		DEBUG = UpdateCore.DEBUG_SHOW_RECONCILER;
		processCommandLine((String[]) args);

		// obtain current platform configuration and save stamps
		IPlatformConfiguration cfg = ConfiguratorUtils.getCurrentPlatformConfiguration();
		// URL[] originalPluginPath = cfg.getPluginPath();

		// perform reconciliation
		long start = 0;
		if (DEBUG) {
			start = new Date().getTime();
			debug("begin"); //$NON-NLS-1$
		}

		if (initialize || firstUse)
			optimistic = true; // initialize and first-time startup ... optimistic
		// (changes are auto-configured)
		else
			optimistic = false; // all other ... pessimistic (changes are
		// reflected in state but not configured)

		boolean changes = reconcile(cfg);

		if (DEBUG) {
			long delta = (new Date().getTime()) - start;
			debug("end [" + delta + "ms]"); //$NON-NLS-1$ //$NON-NLS-2$
		}

		// if we need to write the features available, do it now
		if (dumpfile) {
			dumpFeatures();
		}

		// if we are completing post-install initialization (-initialize)
		// just exit
		if (initialize) {
			Platform.endSplash();
			return EXIT_OK;
		}

		// if the reconciler app was explicitly invoked, mark changes and
		// just exit
		if (RECONCILER_APP.equals(originalApplication)) {
			Platform.endSplash();
			if (changes)
				markChanges(cfg);
			return EXIT_OK; // just exit if original app was reconciler
		}

		// if the reconciler app was invoked, with -dump
		// just exit
		if (dumpfile) {
			Platform.endSplash();
			if (changes)
				markChanges(cfg);
			return EXIT_OK; // just exit 
		}
		
		// see if plugins have changed
		//		if (pluginPathChanged(cfg, originalPluginPath)) {
		// plugins lineup changed ... need to restart
		Platform.endSplash();
		if (changes)
			markChanges(cfg);
		if (DEBUG)
			debug("restarting ..." + new Date()); //$NON-NLS-1$
		return EXIT_RESTART;
		//		} else {
		//			// plugins lineup did not change ... no need to restart, 
		//			// just continue starting up the original app. Original
		//			// app will take down splash
		//			IPlatformRunnable originalRunnable = getRunnable(originalApplication);
		//			if (originalRunnable == null)
		//				throw new IllegalArgumentException(Policy.bind("Reconciler.appNotFound",originalApplication));  //$NON-NLS-1$
		//			if (DEBUG)
		//				debug("invoking " + originalApplication + " ...");  //$NON-NLS-1$  //$NON-NLS-2$
		//			// indicate we have new updates (-newUpdates)	
		//			if (changes)
		//				appArgs = markChanges(appArgs);
		//			return originalRunnable.run(appArgs);
		//		}

	}

	/*
	 * get the list of all installed features in all the sites 
	 * dump the identifier and version in a file
	 */
	private void dumpFeatures() {
		if (dumpFilename == null)
			return;
		List features = new ArrayList();

		// find all features
		IConfiguredSite[] configuredSites = new IConfiguredSite[0];
		try {
			configuredSites = SiteManager.getLocalSite().getCurrentConfiguration().getConfiguredSites();
		} catch (Exception e) {
			// eat the error
		}
		for (int i = 0; i < configuredSites.length; i++) {
			IFeatureReference[] ref = configuredSites[i].getSite().getFeatureReferences();
			try {
				for (int j = 0; j < ref.length; j++) {
					features.add(ref[j].getVersionedIdentifier());
				}
			} catch (Exception e) {
				// eat the exception
			}
		}

		// dump them
		File dumpFile = new File(dumpFilename);
		FileOutputStream out = null;
		try {
			out = new FileOutputStream(dumpFile);

			for (Iterator iter = features.iterator(); iter.hasNext();) {
				VersionedIdentifier element = (VersionedIdentifier) iter.next();
				try {
					String feature = element.getIdentifier() + "," + element.getVersion() + '\n';
					out.write(feature.getBytes());
				} catch (Exception e) {
					// eat the exception
				}
			}
		} catch (Exception e) {
			// eat the exception
			return;
		} finally {
			if (out != null) {
				try {
					out.close();
				} catch (Exception e) {
					// eat the exception
				}
			}
		}

	}

	private boolean reconcile(IPlatformConfiguration cfg) {

		boolean changes = true;

		// do the reconciliation
		try {
			if (DEBUG)
				debug("mode: " + (optimistic ? "optimistic" : "pessimistic")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
			changes = InternalSiteManager.reconcile(optimistic);
			if (DEBUG)
				debug(changes ? "changes detected" : "no changes detected"); //$NON-NLS-1$ //$NON-NLS-2$
		} catch (CoreException e) {
			UpdateCore.warn(null, e);
		} catch (Exception e) {
			UpdateCore.warn(null, e);
		}
		cfg.refresh(); // recompute stamps and plugin path

		return changes;
	}


	private void markChanges(IPlatformConfiguration cfg) {
		// indicate we have changes in restart scenario ... converted to -newUpdates on restart
		FileOutputStream fos = null;
		try {
			URL markerLocation = new URL(cfg.getConfigurationLocation(), CHANGES_MARKER);
			fos = new FileOutputStream(new File(markerLocation.getFile()));
			fos.write(0);
			fos.close();
		} catch (IOException e) {
			if (fos != null)
				try {
					fos.close();
				} catch (IOException e2) {
				}
		}
	}

	private String[] processCommandLine(String[] args) {
		int[] configArgs = new int[100];
		configArgs[0] = -1; // need to initialize the first element to something that could not be an index.
		int configArgIndex = 0;
		for (int i = 0; i < args.length; i++) {
			boolean found = false;

			// check for args without parameters (i.e., a flag arg)

			// look for the initialization flag
			if (args[i].equalsIgnoreCase(INITIALIZE)) {
				initialize = true;
				found = true;
			}

			// look for first use flag
			if (args[i].equalsIgnoreCase(FIRSTUSE)) {
				firstUse = true;
				found = true;
			}

			if (found) {
				configArgs[configArgIndex++] = i;
				continue;
			}

			// check for args with parameters. If we are at the last argument or if the next one
			// has a '-' as the first character, then we can't have an arg with a parm so continue.
			if (i == args.length - 1 || args[i + 1].startsWith("-")) { //$NON-NLS-1$
				continue;
			}
			String arg = args[++i];

			// look for the application argument
			if (args[i - 1].equalsIgnoreCase(APPLICATION)) {
				found = true;
				originalApplication = arg;
			}

			// look for the dumpfile argument
			if (args[i - 1].equalsIgnoreCase(DUMPFILE)) {
				found = true;
				dumpfile = true;
				dumpFilename = arg;
			}

			// done checking for args.  Remember where an arg was found 
			if (found) {
				configArgs[configArgIndex++] = i - 1;
				configArgs[configArgIndex++] = i;
			}
		}

		// remove all the arguments consumed by this argument parsing
		if (configArgIndex == 0)
			return args;
		String[] passThruArgs = new String[args.length - configArgIndex];
		configArgIndex = 0;
		int j = 0;
		for (int i = 0; i < args.length; i++) {
			if (i == configArgs[configArgIndex])
				configArgIndex++;
			else
				passThruArgs[j++] = args[i];
		}
		return passThruArgs;
	}

	private void debug(String s) {
		UpdateCore.debug(this.getClass().getName() + ": " + s); //$NON-NLS-1$
	}
}
