/*******************************************************************************
 * Copyright (c) 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.osgi.internal.resolver;

import java.util.*;

import org.eclipse.core.dependencies.*;

/**
 * This is a variant of Eclipse 2.1 resolution policy that takes into account the current state
 * of the element in a sense that resolved elements tend to stay resolved (the "least perturbation mode").
 */
public class Eclipse30SelectionPolicy implements ISelectionPolicy {
	public Set selectMultiple(IElementSet elementSet) {
		Set selected = new HashSet();
		// pre-select all elements that were previously resolved and are satisfied		
		Collection previouslyResolvedSet = elementSet.getResolved();
		for (Iterator iter = previouslyResolvedSet.iterator(); iter.hasNext();) {
			IElement previouslyResolved = (IElement) iter.next();
			// if the previously resolved element is satisfied, select it
			if (elementSet.getSatisfied().contains(previouslyResolved))
				selected.add(previouslyResolved);
		}
		// may want to select others		
		for (Iterator requiringIter = elementSet.getRequiring().iterator(); requiringIter.hasNext();) {
			IElementSet requiringNode = (IElementSet) requiringIter.next();
			Collection requiringNodeSelectedVersions = requiringNode.getSelected();
			// loop through the selected versions (one if it is a non-library plug-in) of this requiring plug-in
			for (Iterator requiringVersionsIter = requiringNodeSelectedVersions.iterator(); requiringVersionsIter.hasNext();) {
				IElement requiringSelectedVersion = (IElement) requiringVersionsIter.next();
				// the selected version may not require this element set (but it still can be selected)
				IDependency requiringSelectedVersionDependency = requiringSelectedVersion.getDependency(elementSet.getId());
				if (requiringSelectedVersionDependency == null)
					continue;
				// find the best version for this pre-requisite
				IElement bestVersion = null;
				for (Iterator satisfiedIter = elementSet.getSatisfied().iterator(); satisfiedIter.hasNext();) {
					IElement satisfiedVersion = (IElement) satisfiedIter.next();
					boolean satisfiesDependency = requiringSelectedVersionDependency.getMatchRule().isSatisfied(requiringSelectedVersionDependency.getRequiredVersionId(), satisfiedVersion.getVersionId());
					if (satisfiesDependency) {
						boolean betterThanBest = bestVersion == null || elementSet.getSystem().compare(satisfiedVersion.getVersionId(), bestVersion.getVersionId()) > 0;
						if (betterThanBest)
							bestVersion = satisfiedVersion;
					}
				}
				if (bestVersion != null)
					selected.add(bestVersion);
			}
		}
		// if none of the versions are required (or satisfy any selected re-requisites), pick the highest
		if (selected.isEmpty()) {
			IElement bestVersion = null;
			for (Iterator satisfiedIter = elementSet.getSatisfied().iterator(); satisfiedIter.hasNext();) {
				IElement satisfiedVersion = (IElement) satisfiedIter.next();
				boolean betterThanBest = bestVersion == null || elementSet.getSystem().compare(satisfiedVersion.getVersionId(), bestVersion.getVersionId()) > 0;
				if (betterThanBest)
					bestVersion = satisfiedVersion;
			}
			selected = Collections.singleton(bestVersion);
		}
		return selected;
	}

	public IElement selectSingle(IElementSet elementSet) {
		Collection previouslyResolvedSet = elementSet.getResolved();
		// we already have one element resolved
		if (!previouslyResolvedSet.isEmpty()) {
			// TODO: need a cheaper way to obtain the single element
			IElement previouslyResolved = (IElement) previouslyResolvedSet.iterator().next();
			// if it is satisfied, just return it
			if (elementSet.getSatisfied().contains(previouslyResolved))
				return previouslyResolved;
		}

		// none of its versions are required by other element sets - so just pick the highest
		if (elementSet.getRequiring().isEmpty()) {
			// otherwise, pick the highest version
			IElement highest = null;
			for (Iterator satisfiedIter = elementSet.getSatisfied().iterator(); satisfiedIter.hasNext();) {
				IElement satisfiedVersion = (IElement) satisfiedIter.next();
				if (highest == null || elementSet.getSystem().compare(satisfiedVersion.getVersionId(), highest.getVersionId()) > 0)
					highest = satisfiedVersion;
			}
			return highest;
		}

		// let's pick the highest that satisfies all or the highest required
		IElement highest = null;
		int highestStatus = 0; // 0 - not required, 1 - satisfy some, 2 - satisfy all mandatory, 3 - satisfy all
		for (Iterator satisfiedIter = elementSet.getSatisfied().iterator(); satisfiedIter.hasNext();) {
			boolean satisfiesAllMandatory = true;
			boolean satisfiesAll = true;
			boolean isRequired = false;
			IElement satisfiedVersion = (IElement) satisfiedIter.next();
			for (Iterator requiringIter = elementSet.getRequiring().iterator(); requiringIter.hasNext();) {
				IElementSet requiringNode = (IElementSet) requiringIter.next();
				Collection requiringNodeSelectedVersions = requiringNode.getSelected();
				// loop through the selected versions (one if it is a non-library plug-in) of this requiring plug-in
				for (Iterator requiringVersionsIter = requiringNodeSelectedVersions.iterator(); requiringVersionsIter.hasNext();) {
					IElement requiringSelectedVersion = (IElement) requiringVersionsIter.next();
					// the selected version may not require this element set (but it still can be selected)
					IDependency requiringSelectedVersionDep = requiringSelectedVersion.getDependency(elementSet.getId());
					if (requiringSelectedVersionDep != null) {
						boolean satisfiesDependency = requiringSelectedVersionDep.getMatchRule().isSatisfied(requiringSelectedVersionDep.getRequiredVersionId(), satisfiedVersion.getVersionId());
						isRequired |= satisfiesDependency;
						satisfiesAll &= satisfiesDependency;
						satisfiesAllMandatory &= (satisfiesDependency | requiringSelectedVersionDep.isOptional());
					}
				}
			}
			int status = satisfiesAll ? 3 : (satisfiesAllMandatory ? 2 : (isRequired ? 1 : 0));
			boolean higherThanHighest = highest == null || elementSet.getSystem().compare(satisfiedVersion.getVersionId(), highest.getVersionId()) > 0;
			if (status > highestStatus || (status == highestStatus && higherThanHighest)) {
				highest = satisfiedVersion;
				highestStatus = status;
			}
		}
		return highest;
	}

}