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

import java.util.*;

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

/**
 * This class is used to construct a joint feature hiearchy.
 * Old feature reference represents feature that is
 * found on in the current configuration. New feature
 * reference is found in the feature that is an install/update
 * candidate. The element is used to join nodes of the
 * hiearchy formed by including features so that
 * each node in the hiearchy contains references to the
 * old and the new feature. Old and new features have
 * the same IDs but different versions, except in 
 * the case of optional features, where the tree may
 * be constructed to bring in an optional feature
 * that was not installed initially. In that case,
 * some nodes may have old an new references with the
 * same ID and version. 
 * <p>
 * Old feature reference may be null. That means
 * that the older feature with the same ID but lower
 * version was not found in the current configuration.
 */
public class FeatureHierarchyElement {

	private Object root;
	private ArrayList children;
	private IFeatureReference oldFeatureRef;
	private IFeatureReference newFeatureRef;
	private boolean checked;
	private boolean optionalChildren;
	private boolean nativeUpgrade = false;

	public FeatureHierarchyElement(
		IFeatureReference oldRef,
		IFeatureReference newRef) {
		oldFeatureRef = oldRef;
		newFeatureRef = newRef;
	}

	public void setRoot(Object root) {
		this.root = root;
	}

	public Object getRoot() {
		return root;
	}

	/*
	 * Return true if element can be checked, false otherwise.
	 */
	public boolean isEditable() {
		// cannot uncheck non-optional features
		if (isOptional() == false)
			return false;
		// cannot uncheck optional feature that
		// has already been installed
		if (oldFeatureRef != null)
			return false;
		return true;
	}

	/**
	 * A hirearchy node represents a 'false update' if
	 * both old and new references exist and both
	 * point to the feature with the same ID and version.
	 * These nodes will not any bytes to be downloaded - 
	 * they simply exist to allow the hirarchy to
	 * reach the optional children that are missing
	 * and will be installed.
	 */

	public boolean isFalseUpdate() {
		if (oldFeatureRef != null && newFeatureRef != null) {
			try {
				return oldFeatureRef.getVersionedIdentifier().equals(
					newFeatureRef.getVersionedIdentifier());
			} catch (CoreException e) {
			}
		}
		return false;
	}
	/**
	 * Returns true if feature is included as optional.
	 */
	public boolean isOptional() {
		return newFeatureRef instanceof IIncludedFeatureReference
			&& ((IIncludedFeatureReference) newFeatureRef).isOptional();
	}
	/**
	 * Returns true if this optional feature is selected
	 * for installation. Non-optional features or non-editable
	 * features are always checked.
	 */
	public boolean isChecked() {
		return checked;
	}

	void setNativeUpgrade(boolean nativeUpgrade) {
		this.nativeUpgrade = nativeUpgrade;
	}

	/**
	 * Returns true if this optional feature should
	 * be enabled when installed. By default, all
	 * features in the hiearchy should be enabled.
	 * The exception is for optional features that
	 * are updated to a new version in case where
	 * the older version of the optional feature
	 * is disabled in the given configuration. 
	 * In this case, the feature is
	 * updated and disabled in order to maintain
	 * its state.
	 */
	public boolean isEnabled(IInstallConfiguration config) {
		if (nativeUpgrade)
			return true;
		if (isOptional() && oldFeatureRef != null) {
			try {
				IFeature oldFeature = oldFeatureRef.getFeature(null);
				IConfiguredSite csite =
					UpdateUtils.getConfigSite(oldFeature, config);
				return csite.isConfigured(oldFeature);
			} catch (CoreException e) {
			}
		}
		return true;
	}

	public IFeature getFeature() {
		try {
			IFeature feature = newFeatureRef.getFeature(null);
			return feature;
		} catch (CoreException e) {
			return null;
		}
	}

	/**
	 * Selects an editable feature for installation.
	 */
	public void setChecked(boolean checked) {
		this.checked = checked;
	}
	/**
	 * Returns label for UI presentation.
	 */
	public String getLabel() {
		try {
			return getFeatureLabel(newFeatureRef);
		} catch (CoreException e) {
			if (newFeatureRef instanceof IIncludedFeatureReference) {
				String iname =
					((IIncludedFeatureReference) newFeatureRef).getName();
				if (iname != null)
					return iname;
			}
			try {
				VersionedIdentifier vid =
					newFeatureRef.getVersionedIdentifier();
				return vid.toString();
			} catch (CoreException e2) {
			}
		}
		return null;
	}
	/**
	 * Computes label from the feature.
	 */
	private String getFeatureLabel(IFeatureReference featureRef)
		throws CoreException {
		IFeature feature = featureRef.getFeature(null);
		return feature.getLabel()
			+ " " //$NON-NLS-1$
			+ feature.getVersionedIdentifier().getVersion().toString();
	}
	/**
	 * Computes children by linking matching features from the
	 * old feature's and new feature's hierarchy.
	 */
	public FeatureHierarchyElement[] getChildren(
		boolean update,
		boolean patch,
		IInstallConfiguration config) {
		computeChildren(update, patch, config);
		FeatureHierarchyElement[] array =
			new FeatureHierarchyElement[children.size()];
		children.toArray(array);
		return array;
	}

	public FeatureHierarchyElement[] getChildren() {
		if (children != null) {
			FeatureHierarchyElement[] array =
				new FeatureHierarchyElement[children.size()];
			children.toArray(array);
			return array;
		}

		return new FeatureHierarchyElement[0];
	}
	/**
	 * Computes children of this node.
	 */
	public void computeChildren(
		boolean update,
		boolean patch,
		IInstallConfiguration config) {
		if (children == null) {
			children = new ArrayList();
			try {
				IFeature oldFeature = null;
				IFeature newFeature = null;
				newFeature = newFeatureRef.getFeature(null);
				if (oldFeatureRef != null)
					oldFeature = oldFeatureRef.getFeature(null);
				optionalChildren =
					computeElements(
						oldFeature,
						newFeature,
						update,
						patch,
						config,
						children);
				for (int i = 0; i < children.size(); i++) {
					FeatureHierarchyElement element =
						(FeatureHierarchyElement) children.get(i);
					element.setRoot(getRoot());
				}
			} catch (CoreException e) {
			}
		}
	}
	/**
	 * 
	 */
	public boolean hasOptionalChildren() {
		return optionalChildren;
	}
	/**
	 * Adds checked optional features to the provided set.
	 */
	public void addCheckedOptionalFeatures(
		boolean update,
		boolean patch,
		IInstallConfiguration config,
		Set set) {
		if (isOptional() && isChecked()) {
			// Do not add checked optional features
			// if this is an update case but
			// the node is not a 'true' update
			// (old and new feature are the equal)
			if (!update || !isFalseUpdate())
				set.add(newFeatureRef);
		}
		FeatureHierarchyElement[] elements = getChildren(update, patch, config);
		for (int i = 0; i < elements.length; i++) {
			elements[i].addCheckedOptionalFeatures(update, patch, config, set);
		}
	}

	/**
	 * Computes first-level children of the linked hierarchy
	 * for the provided old and new features (same ID, different version
	 * where new version is greater or equal the old version).
	 * Old feature may be null. 
	 */
	public static boolean computeElements(
		IFeature oldFeature,
		IFeature newFeature,
		boolean update,
		boolean patch,
		IInstallConfiguration config,
		ArrayList list) {
		Object[] oldChildren = null;
		Object[] newChildren = getIncludedFeatures(newFeature);
		boolean optionalChildren = false;

		try {
			if (oldFeature != null) {
				oldChildren = getIncludedFeatures(oldFeature);
			}
			for (int i = 0; i < newChildren.length; i++) {
				IFeatureReference oldRef = null;
				IFeatureReference newRef = (IFeatureReference) newChildren[i];
				if (oldChildren != null) {
					String newId =
						newRef.getVersionedIdentifier().getIdentifier();

					for (int j = 0; j < oldChildren.length; j++) {
						IFeatureReference cref =
							(IFeatureReference) oldChildren[j];
						try {
							if (cref
								.getVersionedIdentifier()
								.getIdentifier()
								.equals(newId)) {
								oldRef = cref;
								break;
							}
						} catch (CoreException ex) {
						}
					}
				} else if (patch) {
					// 30849 - find the old reference in the
					// configuration.
					if (!UpdateUtils.isPatch(newFeature)) {
						oldRef = findPatchedReference(newRef, config);
					}
				}
				// test if the old optional feature exists
				if (oldRef != null
					&& ((oldRef instanceof IIncludedFeatureReference
						&& ((IIncludedFeatureReference) oldRef).isOptional())
						|| patch)) {
					try {
						IFeature f = oldRef.getFeature(null);
						if (f == null)
							oldRef = null;
					} catch (CoreException e) {
						// missing
						oldRef = null;
					}
				}
				FeatureHierarchyElement element =
					new FeatureHierarchyElement(oldRef, newRef);
				// If this is an update (old feature exists), 
				// only check the new optional feature if the old exists.
				// Otherwise, always check.
				if (element.isOptional() && (update || patch)) {
					element.setChecked(oldRef != null);
					if (oldRef == null) {
						// Does not have an old reference,
						// but it may contain an older
						// feature that may still qualify
						// for update. For example,
						// an older version may have been
						// installed natively from the CD-ROM.
						if (hasOlderVersion(newRef)) {
							element.setNativeUpgrade(true);
							element.setChecked(true);
						}
					}
				} else
					element.setChecked(true);
				list.add(element);
				element.computeChildren(update, patch, config);
				if (element.isOptional() || element.hasOptionalChildren())
					optionalChildren = true;
			}
		} catch (CoreException e) {
		}
		return optionalChildren;
	}
	public static boolean hasOlderVersion(IFeatureReference newRef) {
		try {
			VersionedIdentifier vid = newRef.getVersionedIdentifier();
			PluginVersionIdentifier version = vid.getVersion();
			String mode = getUpdateVersionsMode();

			IFeature[] allInstalled =
				UpdateUtils.getInstalledFeatures(vid, false);
			for (int i = 0; i < allInstalled.length; i++) {
				IFeature candidate = allInstalled[i];
				PluginVersionIdentifier cversion =
					candidate.getVersionedIdentifier().getVersion();
				// Verify that the difference qualifies as
				// an update.
				if (mode.equals(UpdateCore.EQUIVALENT_VALUE)) {
					if (version.isEquivalentTo(cversion))
						return true;
				} else if (mode.equals(UpdateCore.COMPATIBLE_VALUE)) {
					if (version.isCompatibleWith(cversion))
						return true;
				}
			}
		} catch (CoreException e) {
		}
		return false;
	}

	private static IFeatureReference findPatchedReference(
		IFeatureReference newRef,
		IInstallConfiguration config)
		throws CoreException {
		VersionedIdentifier vid = newRef.getVersionedIdentifier();
		IConfiguredSite[] csites = config.getConfiguredSites();
		for (int i = 0; i < csites.length; i++) {
			IConfiguredSite csite = csites[i];
			IFeatureReference[] refs = csite.getConfiguredFeatures();
			for (int j = 0; j < refs.length; j++) {
				IFeatureReference ref = refs[j];
				VersionedIdentifier refVid = ref.getVersionedIdentifier();
				if (vid.getIdentifier().equals(refVid.getIdentifier()))
					return ref;
			}
		}
		return null;
	}

	/**
	 * Returns included feature references for the given reference.
	 */
	public static Object[] getIncludedFeatures(IFeatureReference ref) {
		try {
			IFeature feature = ref.getFeature(null);
			return getIncludedFeatures(feature);
		} catch (CoreException e) {
		}
		return new Object[0];
	}

	/**
	 * Returns included feature references for the given feature.
	 */

	public static Object[] getIncludedFeatures(IFeature feature) {
		try {
			return feature.getIncludedFeatureReferences();
		} catch (CoreException e) {
		}
		return new Object[0];
	}

	private static String getUpdateVersionsMode() {
		Preferences store = UpdateCore.getPlugin().getPluginPreferences();
		return store.getString(UpdateCore.P_UPDATE_VERSIONS);
	}
}
