/*******************************************************************************
 *  Copyright (c) 2007, 2010 IBM Corporation and others.
 *  All rights reserved. This program and the accompanying materials
 *  are made available under the terms of the Eclipse Public License v1.0
 *  which accompanies this distribution, and is available at
 *  http://www.eclipse.org/legal/epl-v10.html
 * 
 *  Contributors:
 *      IBM Corporation - initial API and implementation
 *      Sonatype, Inc. - ongoing development
 *******************************************************************************/
package org.eclipse.equinox.internal.p2.director;

import java.util.*;
import org.eclipse.core.runtime.*;
import org.eclipse.equinox.internal.p2.core.helpers.LogHelper;
import org.eclipse.equinox.internal.p2.core.helpers.Tracing;
import org.eclipse.equinox.internal.p2.metadata.InstallableUnit;
import org.eclipse.equinox.p2.metadata.*;
import org.eclipse.equinox.p2.metadata.expression.IMatchExpression;
import org.eclipse.equinox.p2.query.*;
import org.eclipse.osgi.util.NLS;

public class Slicer {
	private static boolean DEBUG = false;
	private final IQueryable<IInstallableUnit> possibilites;
	private final boolean considerMetaRequirements;
	protected final IInstallableUnit selectionContext;
	private final Map<String, Map<Version, IInstallableUnit>> slice; //The IUs that have been considered to be part of the problem
	private final MultiStatus result;

	private LinkedList<IInstallableUnit> toProcess;
	private Set<IInstallableUnit> considered; //IUs to add to the slice
	private Set<IInstallableUnit> nonGreedyIUs = new HashSet<IInstallableUnit>(); //IUs that are brought in by non greedy dependencies

	public Slicer(IQueryable<IInstallableUnit> input, Map<String, String> context, boolean considerMetaRequirements) {
		this(input, InstallableUnit.contextIU(context), considerMetaRequirements);
	}

	public Slicer(IQueryable<IInstallableUnit> possibilites, IInstallableUnit selectionContext, boolean considerMetaRequirements) {
		this.possibilites = possibilites;
		this.selectionContext = selectionContext;
		this.considerMetaRequirements = considerMetaRequirements;
		slice = new HashMap<String, Map<Version, IInstallableUnit>>();
		result = new MultiStatus(DirectorActivator.PI_DIRECTOR, IStatus.OK, Messages.Planner_Problems_resolving_plan, null);
	}

	public IQueryable<IInstallableUnit> slice(IInstallableUnit[] ius, IProgressMonitor monitor) {
		try {
			long start = 0;
			if (DEBUG) {
				start = System.currentTimeMillis();
				System.out.println("Start slicing: " + start); //$NON-NLS-1$
			}

			validateInput(ius);
			considered = new HashSet<IInstallableUnit>(Arrays.asList(ius));
			toProcess = new LinkedList<IInstallableUnit>(considered);
			while (!toProcess.isEmpty()) {
				if (monitor.isCanceled()) {
					result.merge(Status.CANCEL_STATUS);
					throw new OperationCanceledException();
				}
				processIU(toProcess.removeFirst());
			}
			if (DEBUG) {
				long stop = System.currentTimeMillis();
				System.out.println("Slicing complete: " + (stop - start)); //$NON-NLS-1$
			}
		} catch (IllegalStateException e) {
			result.add(new Status(IStatus.ERROR, DirectorActivator.PI_DIRECTOR, e.getMessage(), e));
		}
		if (Tracing.DEBUG && result.getSeverity() != IStatus.OK)
			LogHelper.log(result);
		if (result.getSeverity() == IStatus.ERROR)
			return null;
		return new QueryableArray(considered.toArray(new IInstallableUnit[considered.size()]));
	}

	public MultiStatus getStatus() {
		return result;
	}

	//This is a shortcut to simplify the error reporting when the filter of the ius we are being asked to install does not pass
	private void validateInput(IInstallableUnit[] ius) {
		for (int i = 0; i < ius.length; i++) {
			if (!isApplicable(ius[i]))
				throw new IllegalStateException(NLS.bind(Messages.Explanation_missingRootFilter, ius[i]));
		}
	}

	// Check whether the requirement is applicable
	protected boolean isApplicable(IRequirement req) {
		IMatchExpression<IInstallableUnit> filter = req.getFilter();
		return filter == null || filter.isMatch(selectionContext);
	}

	protected boolean isApplicable(IInstallableUnit iu) {
		IMatchExpression<IInstallableUnit> filter = iu.getFilter();
		return filter == null || filter.isMatch(selectionContext);
	}

	protected void processIU(IInstallableUnit iu) {
		iu = iu.unresolved();

		Map<Version, IInstallableUnit> iuSlice = slice.get(iu.getId());
		if (iuSlice == null) {
			iuSlice = new HashMap<Version, IInstallableUnit>();
			slice.put(iu.getId(), iuSlice);
		}
		iuSlice.put(iu.getVersion(), iu);
		if (!isApplicable(iu)) {
			return;
		}

		Collection<IRequirement> reqs = getRequiredCapabilities(iu);
		if (reqs.isEmpty())
			return;
		for (IRequirement req : reqs) {
			if (!isApplicable(req))
				continue;

			if (!isGreedy(req)) {
				nonGreedyIUs.addAll(possibilites.query(QueryUtil.createMatchQuery(req.getMatches()), null).toUnmodifiableSet());
				continue;
			}

			expandRequirement(iu, req);
		}
	}

	protected boolean isGreedy(IRequirement req) {
		return req.isGreedy();
	}

	private Collection<IRequirement> getRequiredCapabilities(IInstallableUnit iu) {
		Collection<IRequirement> iuRequirements = iu.getRequirements();
		int initialRequirementCount = iuRequirements.size();
		if (!(iu instanceof IInstallableUnitPatch)) {
			if (!considerMetaRequirements)
				return iuRequirements;

			Collection<IRequirement> iuMetaRequirements = iu.getMetaRequirements();
			int metaSize = iuMetaRequirements.size();
			if (metaSize == 0)
				return iuRequirements;

			ArrayList<IRequirement> aggregatedCapabilities = new ArrayList<IRequirement>(initialRequirementCount + metaSize);
			aggregatedCapabilities.addAll(iuRequirements);
			aggregatedCapabilities.addAll(iuMetaRequirements);
			return aggregatedCapabilities;
		}

		IInstallableUnitPatch patchIU = (IInstallableUnitPatch) iu;
		List<IRequirementChange> changes = patchIU.getRequirementsChange();
		ArrayList<IRequirement> aggregatedCapabilities = new ArrayList<IRequirement>(initialRequirementCount + changes.size());
		aggregatedCapabilities.addAll(iuRequirements);
		for (int i = 0; i < changes.size(); i++)
			aggregatedCapabilities.add(changes.get(i).newValue());
		return aggregatedCapabilities;
	}

	private void expandRequirement(IInstallableUnit iu, IRequirement req) {
		if (req.getMax() == 0)
			return;
		IQueryResult<IInstallableUnit> matches = possibilites.query(QueryUtil.createMatchQuery(req.getMatches()), null);
		int validMatches = 0;
		for (Iterator<IInstallableUnit> iterator = matches.iterator(); iterator.hasNext();) {
			IInstallableUnit match = iterator.next();
			if (!isApplicable(match))
				continue;
			validMatches++;
			Map<Version, IInstallableUnit> iuSlice = slice.get(match.getId());
			if (iuSlice == null || !iuSlice.containsKey(match.getVersion()))
				consider(match);
		}

		if (validMatches == 0) {
			if (req.getMin() == 0) {
				if (DEBUG)
					System.out.println("No IU found to satisfy optional dependency of " + iu + " on req " + req); //$NON-NLS-1$//$NON-NLS-2$
			} else {
				result.add(new Status(IStatus.WARNING, DirectorActivator.PI_DIRECTOR, NLS.bind(Messages.Planner_Unsatisfied_dependency, iu, req)));
			}
		}
	}

	private void consider(IInstallableUnit match) {
		if (considered.add(match))
			toProcess.addLast(match);
	}

	Set<IInstallableUnit> getNonGreedyIUs() {
		return nonGreedyIUs;
	}
}
