/*******************************************************************************
 * Copyright (c) 2000, 2007 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
 *******************************************************************************/
package org.eclipse.update.internal.search;

import java.util.ArrayList;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.PluginVersionIdentifier;
import org.eclipse.core.runtime.Preferences;
import org.eclipse.update.configuration.IConfiguredSite;
import org.eclipse.update.configuration.IInstallConfiguration;
import org.eclipse.update.configuration.ILocalSite;
import org.eclipse.update.core.IFeature;
import org.eclipse.update.core.IFeatureReference;
import org.eclipse.update.core.IIncludedFeatureReference;
import org.eclipse.update.core.ISite;
import org.eclipse.update.core.ISiteFeatureReference;
import org.eclipse.update.core.IURLEntry;
import org.eclipse.update.core.IUpdateConstants;
import org.eclipse.update.core.SiteManager;
import org.eclipse.update.core.VersionedIdentifier;
import org.eclipse.update.internal.core.Messages;
import org.eclipse.update.internal.core.UpdateCore;
import org.eclipse.update.internal.operations.FeatureHierarchyElement;
import org.eclipse.update.internal.operations.UpdateUtils;
import org.eclipse.update.operations.IInstallFeatureOperation;
import org.eclipse.update.operations.OperationsManager;
import org.eclipse.update.search.IQueryUpdateSiteAdapter;
import org.eclipse.update.search.IUpdateSearchFilter;
import org.eclipse.update.search.IUpdateSearchQuery;
import org.eclipse.update.search.IUpdateSearchResultCollector;

public class UpdatesSearchCategory extends BaseSearchCategory {
	private static final String CATEGORY_ID =
		"org.eclipse.update.core.new-updates"; //$NON-NLS-1$
	private IFeature [] features;
	private boolean automatic;

	class Candidate {
		ArrayList children;
		Candidate parent;
		IFeatureReference ref;
		public Candidate(IFeatureReference ref) {
			this.ref = ref;
		}
		public Candidate(IFeatureReference ref, Candidate parent) {
			this(ref);
			this.parent = parent;
		}
		public void add(Candidate child) {
			if (children == null)
				children = new ArrayList();
			child.setParent(this);
			children.add(child);
		}
		void setParent(Candidate parent) {
			this.parent = parent;
		}
		public IFeatureReference getReference() {
			return ref;
		}
		void setReference(IFeatureReference ref) {
			this.ref = ref;
		}
		public IFeature getFeature(IProgressMonitor monitor) {
			try {
				return ref.getFeature(monitor);
			} catch (CoreException e) {
				return null;
			}
		}
		public Candidate getParent() {
			return parent;
		}
		public Candidate getRoot() {
			Candidate root = this;

			while (root.getParent() != null) {
				root = root.getParent();
			}
			return root;
		}
		public IURLEntry getUpdateEntry() {
			int location = IUpdateConstants.SEARCH_ROOT;

			if (ref instanceof IIncludedFeatureReference)
				location =
					((IIncludedFeatureReference) ref).getSearchLocation();
			if (parent == null || location == IUpdateConstants.SEARCH_SELF) {
				return getFeature(null).getUpdateSiteEntry();
			}
			return getRoot().getUpdateEntry();
		}
		public String toString() {
			return ref.toString();
		}
		public boolean equals(Object source) {
			if (source instanceof Candidate) {
				return this.ref.equals(((Candidate) source).getReference());
			}
			if (source instanceof IFeatureReference) {
				return this.ref.equals(source);
			}
			return false;
		}
		public void addToFlatList(ArrayList list, boolean updatableOnly) {
			// add itself
			if (!updatableOnly || isUpdatable())
				list.add(this);
			// add children
			if (children != null) {
				for (int i = 0; i < children.size(); i++) {
					Candidate child = (Candidate) children.get(i);
					child.addToFlatList(list, updatableOnly);
				}
			}
		}
		public boolean isUpdatable() {
			return (parent == null);
		}
	}

	private static class Hit {
		IFeature candidate;
		IFeatureReference ref;
		IInstallFeatureOperation patchFor;
		boolean patch;
		IInstallFeatureOperation job;
		
		public Hit(IFeature candidate, IFeatureReference ref) {
			this.candidate = candidate;
			this.ref = ref;
		}
		public Hit(IFeature candidate, IFeatureReference ref, boolean patch) {
			this(candidate, ref);
			this.patch = patch;
		}

		public Hit(IFeature candidate, IFeatureReference ref, IInstallFeatureOperation patchFor) {
			this(candidate, ref, true);
			this.patchFor = patchFor;
		}

		public IInstallFeatureOperation getJob() {
			if (job == null) {
				try {
					IFeature feature = ref.getFeature(null);
					job = OperationsManager.getOperationFactory().createInstallOperation(null, feature, null, null, null);
				} catch (CoreException e) {
					UpdateCore.log(e);
				}
			}
			return job;
		}

		public boolean isPatch() {
			return patch;
		}
		public IInstallFeatureOperation getPatchedJob() {
			return patchFor;
		}
	}

	public class UpdateQuery implements IUpdateSearchQuery {
		IFeature candidate;
		IQueryUpdateSiteAdapter adapter;

		public UpdateQuery(
			IFeature candidate,
			IURLEntry updateEntry) {
			this.candidate = candidate;
			if (updateEntry != null && updateEntry.getURL() != null)
				adapter =
					new QueryUpdateSiteAdapter(
						getLabelForEntry(updateEntry),
						updateEntry.getURL(),
						candidate.getVersionedIdentifier().getIdentifier());
		}
		private String getLabelForEntry(IURLEntry entry) {
			String label = entry.getAnnotation();
			if (label == null || label.length() == 0)
				label = entry.getURL().toString();
			return label;
		}

		public IQueryUpdateSiteAdapter getQuerySearchSite() {
			return adapter;
		}
		private boolean isBroken() {
			try {
				IStatus status =
					SiteManager.getLocalSite().getFeatureStatus(candidate);
				return status.getSeverity() == IStatus.ERROR;
			} catch (CoreException e) {
				return false;
			}
		}
		private boolean isMissingOptionalChildren(IFeature feature) {
			try {
				IIncludedFeatureReference[] children =
					feature.getIncludedFeatureReferences();
				for (int i = 0; i < children.length; i++) {
					IIncludedFeatureReference ref = children[i];
					try {
						IFeature child = ref.getFeature(null);
						// If we are here, the child is not missing.
						// Check it's children recursively.
						if (isMissingOptionalChildren(child))
							return true;
					} catch (CoreException e) {
						// Missing child. Return true if optional,
						// otherwise it is a broken feature that we 
						// do not care about.
						if (ref.isOptional()) {
							return FeatureHierarchyElement.hasOlderVersion(ref);
						}
					}
				}
			} catch (CoreException e) {
			}
			return false;
		}
		public void run(
			ISite site,
			String[] categoriesToSkip,
			IUpdateSearchFilter filter,
			IUpdateSearchResultCollector collector,
			IProgressMonitor monitor) {
			ArrayList hits = new ArrayList();
			boolean broken = isBroken();
			boolean missingOptionalChildren = false;

			// Don't bother to compute missing optional children
			// if the feature is broken - all we want is to 
			// see if we should allow same-version re-install.
			if (!broken)
				missingOptionalChildren = isMissingOptionalChildren(candidate);
			ISiteFeatureReference[] refs = site.getFeatureReferences();
			monitor.beginTask("", refs.length + 1); //$NON-NLS-1$
			ArrayList updateJobs = new ArrayList();
			for (int i = 0; i < refs.length; i++) {
				ISiteFeatureReference ref = refs[i];
				try {
					if (isNewerVersion(candidate.getVersionedIdentifier(),ref.getVersionedIdentifier())) {
						Hit h = new Hit(candidate, ref);
						hits.add(h);
						IInstallFeatureOperation job = h.getJob();
						if (job != null)
							updateJobs.add(job);
					} else {
						// accept the same feature if the installed
						// feature is broken
						if ((broken || missingOptionalChildren)
							&& candidate.getVersionedIdentifier().equals(
								ref.getVersionedIdentifier())){
							hits.add(new Hit(candidate, ref));
							continue;
						}
						else {
							// check for patches
							if (isPatch(candidate, ref)){
								hits.add(new Hit(candidate, ref, true));
								continue;
							}
						}
					}
				} catch (CoreException e) {
				}
				monitor.worked(1);
				if (monitor.isCanceled()){
					return;
				}
				
			}
			// accept patches for updated features
			for (int n = 0; n < updateJobs.size(); n++) {
				IInstallFeatureOperation job = (IInstallFeatureOperation) updateJobs
						.get(n);
					IFeature newCandidate = job.getFeature();
					for (int i = 0; i < refs.length; i++) {
						ISiteFeatureReference ref = refs[i];
						if (isPatch(newCandidate, ref)) {
							Hit h = new Hit(newCandidate, ref, job);
							hits.add(h);
							continue;
						}
						//monitor.worked(1);
						if (monitor.isCanceled()) {
							return;
						}
					}
			}
			if (hits.size() > 0) {
				collectValidHits(hits, filter, collector);
			}
			monitor.worked(1);
			monitor.done();
		}
		
		/**
		 * Returns IFeature associated with the IUpdateSearchQuery
		 */
		public IFeature getFeature() {
			return candidate;
		}
	}

	private ArrayList candidates;

	public UpdatesSearchCategory() {
		this(true);
	}
	
	public UpdatesSearchCategory(boolean automatic) {
		super(CATEGORY_ID);
		this.automatic = automatic;
	}

	private void collectValidHits(
		ArrayList hits,
		IUpdateSearchFilter filter,
		IUpdateSearchResultCollector collector) {
		//Object[] array = hits.toArray();
		IFeature topHit = null;
		for (int i = 0; i < hits.size(); i++) {
			Hit hit = (Hit) hits.get(i);
			IInstallFeatureOperation job = hit.getJob();
			if (job == null)
				continue;
			// do not accept updates without a license
			if (!UpdateUtils.hasLicense(job.getFeature())) {
				UpdateCore.log(job.getFeature().getVersionedIdentifier() + ": " + Messages.DefaultFeatureParser_NoLicenseText, null);  //$NON-NLS-1$
				continue;
			}
			IStatus status = null;
			
			// Fix for https://bugs.eclipse.org/bugs/show_bug.cgi?id=132450
			// Only validate for automatic updates because
			// non-automatic once will arrive in the review wizard
			// where additional validation will be performed
			if (automatic) {
				if( hit.getPatchedJob()==null){
					status = OperationsManager.getValidator().validatePendingInstall(job.getOldFeature(), job.getFeature());
				}else{
					status = OperationsManager.getValidator().validatePendingChanges(new IInstallFeatureOperation[]{hit.getPatchedJob(), job});
				}
			}
			if (status == null || status.getCode() == IStatus.WARNING) {
				if (hit.isPatch()) {
					IFeature patch = job.getFeature();
					// Do not add the patch if already installed
					IFeature[] sameId = UpdateUtils.getInstalledFeatures(patch, false);
					if (sameId.length==0) {
						if (filter.accept(patch))
							collector.accept(patch);
					}
				}
				else  {
					topHit = job.getFeature();
					if (filter.accept(topHit))
						collector.accept(topHit);
				}
			}
		}
	}

	private void initialize() {
		candidates = new ArrayList();
		try {
			ILocalSite localSite = SiteManager.getLocalSite();
			IInstallConfiguration config = localSite.getCurrentConfiguration();
			IConfiguredSite[] isites = config.getConfiguredSites();
			for (int i = 0; i < isites.length; i++) {
				contributeCandidates(isites[i]);
			}
		} catch (CoreException e) {
			UpdateCore.log(
				Messages.UpdatesSearchCategory_errorSearchingForUpdates, 
				e);
		}
	}

	private void contributeCandidates(IConfiguredSite isite)
		throws CoreException {
		IFeatureReference[] refs = isite.getConfiguredFeatures();
		ArrayList candidatesPerSite = new ArrayList();
		for (int i = 0; i < refs.length; i++) {
			IFeatureReference ref = refs[i];
			// Don't waste time searching for updates to 
			// patches.
			try {
				if (UpdateUtils.isPatch(ref.getFeature(null)))
					continue;
			}
			catch (CoreException e) {
				continue;
			}
			Candidate c = new Candidate(ref);
			candidatesPerSite.add(c);
		}
		// Create a tree from a flat list
		buildHierarchy(candidatesPerSite);
		// Add the remaining root candidates to 
		// the global list of candidates.
		candidates.addAll(candidatesPerSite);
	}

	private void buildHierarchy(ArrayList candidates) throws CoreException {
		Candidate[] array =
			(Candidate[]) candidates.toArray(new Candidate[candidates.size()]);
		// filter out included features so that only top-level features remain on the list
		for (int i = 0; i < array.length; i++) {
			Candidate parent = array[i];
			IFeature feature = parent.getFeature(null);
			IFeatureReference[] included =
				feature.getIncludedFeatureReferences();
			for (int j = 0; j < included.length; j++) {
				IFeatureReference fref = included[j];
				Candidate child = findCandidate(candidates, fref);
				if (child != null) {
					parent.add(child);
					child.setReference(fref);
					candidates.remove(child);
				}
			}
		}
	}
	private Candidate findCandidate(ArrayList list, IFeatureReference ref) {
		for (int i = 0; i < list.size(); i++) {
			Candidate c = (Candidate) list.get(i);
			if (c.ref.equals(ref))
				return c;
		}
		return null;
	}

	public IUpdateSearchQuery[] getQueries() {
		initialize();
		ArrayList allCandidates = getAllCandidates();

		IUpdateSearchQuery[] queries =
			new IUpdateSearchQuery[allCandidates.size()];
		for (int i = 0; i < queries.length; i++) {
			Candidate candidate = (Candidate) allCandidates.get(i);
			IFeature feature = candidate.getFeature(null);
			IURLEntry updateEntry = candidate.getUpdateEntry();
			if (feature == null) {
				queries[i] = null;
			} else {
				queries[i] = new UpdateQuery(feature, updateEntry);
			}
		}
		return queries;
	}
	
/**
 * Sets the features for which new updates need to be found. If
 * not set, updates will be searched for all the installed
 * and configured features.
 * @param features the features to search updates for
 */	
	public void setFeatures(IFeature [] features) {
		this.features = features;
	}
	
/**
 * Returns an array of features for which updates need to
 * be found. 
 * @return an array of features or <samp>null</samp> if not
 * set.
 */	
	public IFeature [] getFeatures() {
		return features;
	}
	/**
	 * @param fvi
	 * @param cvi
	 * @return fvi < cvi
	 */
	private boolean isNewerVersion(
		VersionedIdentifier fvi,
		VersionedIdentifier cvi) {
		if (!fvi.getIdentifier().equals(cvi.getIdentifier()))
			return false;
		PluginVersionIdentifier fv = fvi.getVersion();
		PluginVersionIdentifier cv = cvi.getVersion();
		String mode = getUpdateVersionsMode();
		boolean greater = cv.isGreaterThan(fv);
		if (!greater)
			return false;
		if (mode.equals(UpdateCore.EQUIVALENT_VALUE))
			return cv.isEquivalentTo(fv);
		else if (mode.equals(UpdateCore.COMPATIBLE_VALUE))
			return cv.isCompatibleWith(fv);
		else
			return false;
	}

	private boolean isPatch(IFeature candidate, ISiteFeatureReference ref) {
		if (ref.isPatch() == false)
			return false;
		try {
			IFeature feature = ref.getFeature(null);
			if( UpdateUtils.isPatch(candidate, feature))
				return true;
			// Check if patch is for children
			try {
				IIncludedFeatureReference[] children =
					candidate.getIncludedFeatureReferences();
				for (int i = 0; i < children.length; i++) {
					IIncludedFeatureReference cref = children[i];
					try {
						IFeature child = cref.getFeature(null);
						if (isPatch(child, ref))
							return true;
					} catch (CoreException e) {
					}
				}
			} catch (CoreException e) {
			}
			return false;
		} catch (CoreException e) {
			return false;
		}
	}
	
	private String getUpdateVersionsMode() {
		Preferences store = UpdateCore.getPlugin().getPluginPreferences();
		return store.getString(UpdateCore.P_UPDATE_VERSIONS);
	}
/*
 * This method recursively walks the list of candidates
 * building the flat that starts with the roots but
 * also includes all the children that are updatable
 * (use 'include' clause with a match that is not 'perfect').
 */
	private ArrayList getAllCandidates() {
		ArrayList selected = new ArrayList();
		for (int i=0; i<candidates.size(); i++) {
			Candidate c = (Candidate)candidates.get(i);
			if (isOnTheList(c))
				c.addToFlatList(selected, true);
		}
		return selected;
	}
	
	private boolean isOnTheList(Candidate c) {
		if (features==null) return true;
		VersionedIdentifier vid;
		try {
			vid = c.getReference().getVersionedIdentifier();
		}
		catch (CoreException e) {
			return false;
		}
		for (int i=0; i<features.length; i++) {
			IFeature feature = features[i];
			VersionedIdentifier fvid = feature.getVersionedIdentifier();
			if (fvid.equals(vid))
				return true;
		}
		return false;
	}
}
