/*******************************************************************************
 * Copyright (c) 2000, 2004 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.configurator.*;
import org.eclipse.update.core.*;
import org.eclipse.update.core.model.*;
import org.eclipse.update.internal.model.*;

/**
 * 
 */
public class ConfigurationPolicy extends ConfigurationPolicyModel {

	/**
	 * Constructor for ConfigurationPolicyModel.
	 */
	public ConfigurationPolicy() {
	}

	/**
	 * Copy Constructor for ConfigurationPolicyModel.
	 */
	public ConfigurationPolicy(ConfigurationPolicy configPolicy) {
		super();
		setPolicy(configPolicy.getPolicy());
		setConfiguredFeatureReferences(configPolicy.getConfiguredFeatures());
		setUnconfiguredFeatureReferences(configPolicy.getUnconfiguredFeatures());
		setConfiguredSiteModel(configPolicy.getConfiguredSiteModel());
	}

	/**
	 * @since 2.0
	 */
	private boolean isUnconfigured(IFeatureReference featureReference) {

		if (featureReference == null)
			return false;

		// returns true if the feature is part of the configured list
		IFeatureReference[] refs = getUnconfiguredFeatures();
		for (int i = 0; i < refs.length; i++) {
			if (featureReference.equals(refs[i])) {
				return true;
			}
		}
		return false;
	}

	/**
	 * @since 2.0
	 */
	public boolean isConfigured(IFeatureReference featureReference) {

		if (featureReference == null)
			return false;

		// returns true if the feature is part of the configured list
		IFeatureReference[] refs = getConfiguredFeatures();
		for (int i = 0; i < refs.length; i++) {
			if (featureReference.equals(refs[i])) {
				return true;
			}
		}
		return false;
	}

	/**
	 * adds the feature to the list of features if the policy is USER_INCLUDE
	 */
	public void configure(IFeatureReference featureReference, boolean callInstallHandler, boolean createActivity) throws CoreException {

		if (isConfigured(featureReference)) // already configured
			return;

		if (featureReference == null) {
			UpdateCore.warn("The feature reference to configure is null"); //$NON-NLS-1$
			return;
		}

		IFeature feature = null;
		try {
			feature = featureReference.getFeature(null);
		} catch (CoreException e) {
			if (!UpdateManagerUtils.isOptional(featureReference)) {
				URL url = featureReference.getURL();
				String urlString = (url != null) ? url.toExternalForm() : "<no feature reference url>"; //$NON-NLS-1$
				UpdateCore.warn("Error retrieving feature:" + urlString, e); //$NON-NLS-1$
				return;
			}
		}
		if (feature == null) {
			URL url = featureReference.getURL();
			String urlString = (url != null) ? url.toExternalForm() : "<no feature reference url>"; //$NON-NLS-1$
			UpdateCore.warn("The feature to unconfigure is null: feature reference is:" + urlString); //$NON-NLS-1$
		}

		// Setup optional install handler
		InstallHandlerProxy handler = null;
		if (callInstallHandler && feature.getInstallHandlerEntry() != null)
			handler = new InstallHandlerProxy(IInstallHandler.HANDLER_ACTION_CONFIGURE, feature, feature.getInstallHandlerEntry(), null);
		boolean success = false;
		Throwable originalException = null;

		// do the configure action
		try {
			if (handler != null)
				handler.configureInitiated();

			ConfigurationActivity activity = null;
			if (createActivity) {
				activity = new ConfigurationActivity(IActivity.ACTION_CONFIGURE);
				activity.setLabel(feature.getVersionedIdentifier().toString());
				activity.setDate(new Date());
			}

			addConfiguredFeatureReference((FeatureReferenceModel) featureReference);

			// everything done ok
			if (activity != null) {
				InstallConfiguration installConfig = (InstallConfiguration) SiteManager.getLocalSite().getCurrentConfiguration();
				activity.setStatus(IActivity.STATUS_OK);
				installConfig.addActivity(activity);
			}

			if (handler != null)
				handler.completeConfigure();

			success = true;
		} catch (Throwable t) {
			originalException = t;
		} finally {
			Throwable newException = null;
			try {
				if (handler != null)
					handler.configureCompleted(success);
			} catch (Throwable t) {
				newException = t;
			}
			if (originalException != null) // original exception wins
				throw Utilities.newCoreException(Policy.bind("InstallHandler.error", feature.getLabel()), originalException); //$NON-NLS-1$
			if (newException != null)
				throw Utilities.newCoreException(Policy.bind("InstallHandler.error", feature.getLabel()), newException); //$NON-NLS-1$
		}
	}

	/**
	 * check if the plugins to unconfigure are required by other configured feature and
	 * adds the feature to the list of unconfigured features 
	 */
	public boolean unconfigure(IFeatureReference featureReference, boolean callInstallHandler, boolean createActivity) throws CoreException {

		if (isUnconfigured(featureReference)) {
			UpdateCore.warn("Feature already unconfigured"); //$NON-NLS-1$
			return true;
		}

		if (featureReference == null) {
			UpdateCore.warn("The feature reference to unconfigure is null"); //$NON-NLS-1$
			return false;
		}

		IFeature feature = null;
		try {
			feature = featureReference.getFeature(null);
		} catch (CoreException e) {
			if (!UpdateManagerUtils.isOptional(featureReference)) {
				URL url = featureReference.getURL();
				String urlString = (url != null) ? url.toExternalForm() : "<no feature reference url>"; //$NON-NLS-1$
				UpdateCore.warn("Error retrieving feature:" + urlString, e); //$NON-NLS-1$
				return false;
			}
		}

		if (feature == null) {
			URL url = featureReference.getURL();
			String urlString = (url != null) ? url.toExternalForm() : "<no feature reference url>"; //$NON-NLS-1$
			UpdateCore.warn("The feature to unconfigure is null: feature reference is:" + urlString); //$NON-NLS-1$
			return false;
		}

		// Setup optional install handler
		InstallHandlerProxy handler = null;
		if (callInstallHandler && feature.getInstallHandlerEntry() != null) {
			handler = new InstallHandlerProxy(IInstallHandler.HANDLER_ACTION_UNCONFIGURE, feature, feature.getInstallHandlerEntry(), null);
		}

		boolean success = false;
		Throwable originalException = null;

		// do the unconfigure action
		try {

			ConfigurationActivity activity = null;
			if (createActivity) {
				activity = new ConfigurationActivity(IActivity.ACTION_UNCONFIGURE);
				activity.setLabel(feature.getVersionedIdentifier().toString());
				activity.setDate(new Date());
			}

			InstallConfiguration installConfig = null;

			// only ask for install config is activity created.
			// prevents loops during reconciliation
			if (activity != null)
				installConfig = ((InstallConfiguration) SiteManager.getLocalSite().getCurrentConfiguration());

			// Allow unconfigure if the feature is optional from all the parents
			// or if the feature is mandatory and non of its parent are configured
			// removed, not a core issue (so deep down)
			//if (validateNoConfiguredParents(feature)) {
			if (handler != null)
				handler.unconfigureInitiated();
			addUnconfiguredFeatureReference((FeatureReferenceModel) featureReference);
			if (handler != null)
				handler.completeUnconfigure();

			// everything done ok
			if (activity != null) {
				activity.setStatus(IActivity.STATUS_OK);
				installConfig.addActivity(activity);
			}
			success = true;
			//} else {
			//	if (activity != null) {
			//		activity.setStatus(IActivity.STATUS_NOK);
			//		installConfig.addActivityModel((ConfigurationActivityModel) activity);
			//	}
			//}
		} catch (Throwable t) {
			originalException = t;
		} finally {
			Throwable newException = null;
			try {
				if (handler != null)
					handler.unconfigureCompleted(success);
			} catch (Throwable t) {
				newException = t;
			}
			if (originalException != null) // original exception wins
				throw Utilities.newCoreException(Policy.bind("InstallHandler.error", feature.getLabel()), originalException); //$NON-NLS-1$
			if (newException != null)
				throw Utilities.newCoreException(Policy.bind("InstallHandler.error", feature.getLabel()), newException); //$NON-NLS-1$
		}

		if (!success) {
			URL url = featureReference.getURL();
			String urlString = (url != null) ? url.toExternalForm() : "<no feature reference url>"; //$NON-NLS-1$
			UpdateCore.warn("Unable to unconfigure:" + urlString); //$NON-NLS-1$
		}
		return success;
	}

	/**
	 * Calculates the plugin list for the policy. For "INCLUDE" policy, this
	 * corresponds to the plugins for configured features. For "EXCLUDE"
	 * policy, this corresponds to the plugins for unconfigured features that
	 * are not referenced by any configured features.
	 */
	public String[] getPluginPath(ISite site) throws CoreException {
		String[] pluginPaths;
		// Note: Since 3.0M7 we leave patched features configured,
		// and take this into account when computing configured plugins
		// all unconfigured features. Note that patched features are still
		// configured
		IFeatureReference[] unconfiguredFeatures = getUnconfiguredFeatures();
		// all configured features, including patches and patched features
		IFeatureReference[] configuredFeatures = getConfiguredFeatures();
		if (!isEnabled()) {
			if (getPolicy() == IPlatformConfiguration.ISitePolicy.USER_INCLUDE) {
				// disabled site, INCLUDE policy
				pluginPaths = new String[0];
			} else {
				// disabled site, EXCLUDE policy
				pluginPaths = getAllKnownPluginStrings(site,
						configuredFeatures, unconfiguredFeatures);
			}
		} else {
			// PatchedFeatures (may have no patches) with corresponding patches
			PatchedFeature[] patchedFeatures = buildPatchedFeatures(configuredFeatures);
			if (getPolicy() == IPlatformConfiguration.ISitePolicy.USER_INCLUDE) {
				// enabled site, INCLUDE policy
				pluginPaths = getConfiguredPluginStrings(site, patchedFeatures);
			} else {
				// enabled site, EXCLUDE policy - the usual scenario for local
				// site.
				// return all known MINUS configured plugins
				pluginPaths = subtract(getAllKnownPluginStrings(site,
						configuredFeatures, unconfiguredFeatures),
						getConfiguredPluginStrings(site, patchedFeatures));
			}
		}
		//TRACE
		if (UpdateCore.DEBUG && UpdateCore.DEBUG_SHOW_RECONCILER) {
			UpdateCore
					.debug("GetPluginPath for: " //$NON-NLS-1$
							+ ((site == null) ? "<No site>" : site.getURL() //$NON-NLS-1$
									.toString()));
			for (int i = 0; i < pluginPaths.length; i++) {
				UpdateCore.debug("To write:" + pluginPaths[i]); //$NON-NLS-1$
			}
		}
		return pluginPaths;
	}
	
	/**
	 * Obtains PatchedFeatures - non patch features with corresponding patches if any
	 * 
	 * @param features
	 *            array of features to operate with
	 * @return Patches
	 */
	private PatchedFeature[] buildPatchedFeatures(IFeatureReference[] features) {
		// PatchedFeatures by VersionedIdentifier
		Map map = new HashMap();
		// Create a map of features (not patches)
		for (int f = 0; f < features.length; f++) {
			IFeatureReference featureRef = features[f];
			try {
				if(featureRef.isPatch()){
					continue;
				}
				VersionedIdentifier vi = featureRef.getVersionedIdentifier();
				map.put(vi, new PatchedFeature(features[f]));
			} catch (CoreException e) {
				UpdateCore.warn(null, e);
			}
		}
		// attach patches to features
		for (int f = 0; f < features.length; f++) {
			IFeatureReference patchCandidate = features[f];
			try {
				IFeature feature = patchCandidate.getFeature(null);
				IImport[] imports = feature.getImports();
				for (int i = 0; i < imports.length; i++) {
					IImport oneImport = imports[i];
					if (!oneImport.isPatch())
						continue;
					// it is a patch for
					VersionedIdentifier patchedIdentifier =
						oneImport.getVersionedIdentifier();
					PatchedFeature pf=(PatchedFeature) map.get(patchedIdentifier);
					if (pf!=null) {
						pf.addPatch(patchCandidate);
					} else {
						// patched feature not enabled
					}
				}
			} catch (CoreException e) {
				UpdateCore.warn(null, e);
			}
		}
		Collection patchedFeatures=map.values();
		return (PatchedFeature[])patchedFeatures.toArray(new PatchedFeature[patchedFeatures.size()]);
	}
	
	/**
	 * @since 2.0
	 */
	public IFeatureReference[] getConfiguredFeatures() {
		FeatureReferenceModel[] result = getConfiguredFeaturesModel();
		if (result.length == 0)
			return new IFeatureReference[0];
		else
			return (IFeatureReference[]) result;
	}

	/**
	 * @since 2.0
	 */
	public IFeatureReference[] getUnconfiguredFeatures() {
		FeatureReferenceModel[] result = getUnconfiguredFeaturesModel();
		if (result.length == 0)
			return new IFeatureReference[0];
		else
			return (IFeatureReference[]) result;
	}

	/**
	 * Gets the configuredSite.
	 * @return Returns a IConfiguredSite
	 */
	public IConfiguredSite getConfiguredSite() {
		return (IConfiguredSite) getConfiguredSiteModel();
	}

	/**
	 * removes a feature reference
	 */
	public void removeFeatureReference(IFeatureReference featureRef) {
		if (featureRef instanceof FeatureReferenceModel) {
			removeFeatureReference((FeatureReferenceModel) featureRef);
		}
	}

	/**
	 * @return an array of plugin path for the array of feature reference. For
	 *         features that have patches, plugin path will
	 *         point to plugin with the same ID provided by the patch if it
	 *         exists. Each plugin path only appears once [bug 21750]
	 */
	private String[] getConfiguredPluginStrings(ISite site, PatchedFeature[] features) throws CoreException {
		if (UpdateCore.DEBUG && UpdateCore.DEBUG_SHOW_CONFIGURATION){
			UpdateCore.warn("CONFIGURED PLUGINS"); //$NON-NLS-1$
		}
	
		// Use set to eliminate plugins with same ID and version.
		// Different versions of plugins with same ID are allowed if coming from different features
		Set featurePlugins = new HashSet();
		for (int i = 0; i < features.length; i++) {
			FeaturePlugin[] plugins = features[i].getPlugins();
			featurePlugins.addAll(Arrays.asList(plugins));
		}
		Set pluginStrings = getPluginStrings(site, (FeaturePlugin[]) featurePlugins.toArray(new FeaturePlugin[featurePlugins.size()]));
		return (String[]) pluginStrings.toArray(new String[pluginStrings.size()]);
	}
	/**
	 * @return an array of plugin path for every plugin in known features
	 */
	private String[] getAllKnownPluginStrings(ISite site, IFeatureReference[] configured,IFeatureReference[] unconfigured) throws CoreException {
		if (UpdateCore.DEBUG && UpdateCore.DEBUG_SHOW_CONFIGURATION){
			UpdateCore.warn("ALL PLUGINS"); //$NON-NLS-1$
		}
		// Add features, patched features, or patches
		IFeatureReference[] all=new IFeatureReference[configured.length+unconfigured.length];
		System.arraycopy(configured, 0, all, 0, configured.length);
		System.arraycopy(unconfigured, 0, all, configured.length, unconfigured.length);
		//
		Set patchedPlugins = new HashSet();
		for (int i=0; i< all.length; i++) {
			try {
				IFeature feature = all[i].getFeature(null);
				if (feature == null) {
					UpdateCore.warn("Null Feature", new Exception()); //$NON-NLS-1$
					continue;
				}

				IPluginEntry[] entries = feature.getPluginEntries();
				// add every plugin to the map
				for (int entr = 0; entr < entries.length; entr++) {
					patchedPlugins.add(new FeaturePlugin(entries[entr], feature));
				}

			} catch (CoreException e) {
				UpdateCore.warn(null, e);
			}
		}
		Set pluginStrings = getPluginStrings(site,  (FeaturePlugin[])patchedPlugins.toArray(new FeaturePlugin[patchedPlugins.size()]));
		return (String[]) pluginStrings.toArray(new String[pluginStrings.size()]);
	}
	/**
	 * @param site
	 * @param plugins[]
	 * @return valid string pointing to plugins in given features
	 * @throws CoreException
	 */
	private Set getPluginStrings(ISite site, FeaturePlugin[] plugins) throws CoreException {
		Set pluginStrings=new HashSet();
		for (int i=0; i< plugins.length; i++) {
			IPluginEntry entry = plugins[i].getEntry();
			IFeature feature=plugins[i].getFeature();

			// obtain the path of the plugin directories on the site
			ContentReference[] featureContentReference = null;
			try {
				featureContentReference = feature.getFeatureContentProvider().getPluginEntryArchiveReferences(entry, null /*IProgressMonitor*/
				);
			} catch (CoreException e) {
				UpdateCore.warn(null, e);
			}

			// transform into a valid String
			if (featureContentReference != null) {
				for (int j = 0; j < featureContentReference.length; j++) {
					URL url = site.getSiteContentProvider().getArchiveReference(featureContentReference[j].getIdentifier());
					if (url != null) {
						// make it relative to the site
						String path = UpdateManagerUtils.getURLAsString(site.getURL(), url);
						// add end "/"
						path += (path.endsWith(File.separator) || path.endsWith("/")) ? "" : "/"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
						pluginStrings.add(path);
						if (UpdateCore.DEBUG && UpdateCore.DEBUG_SHOW_CONFIGURATION)
							UpdateCore.warn("Add plugin: " + path + " to the list"); //$NON-NLS-1$ //$NON-NLS-2$
					}
				}
			}
		}
		return pluginStrings;
	}

	/**
	 *	 Obtains strings existing in the allStrings array, but not in the stringsToRemove
	 */
	private String[] subtract(String[] allStrings, String[] stringsToRemove) {
		HashSet resultList = new HashSet(Arrays.asList(allStrings));
		resultList.removeAll(Arrays.asList(stringsToRemove));
		return (String[])resultList.toArray(new String[resultList.size()]);
	}
}
