/*******************************************************************************
 * 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()
			+ " "
			+ 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.
	 * @return true if some of the children are optional, false otherwise.
	 */
	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);
	}
}
