/*******************************************************************************
 * Copyright (c) 2007, 2008 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.equinox.internal.p2.garbagecollector;

import java.util.*;
import org.eclipse.core.runtime.*;
import org.eclipse.equinox.internal.p2.core.helpers.LogHelper;
import org.eclipse.equinox.internal.provisional.p2.artifact.repository.IArtifactRepository;
import org.eclipse.equinox.internal.provisional.p2.engine.IProfile;
import org.eclipse.equinox.internal.provisional.p2.engine.IProfileRegistry;
import org.eclipse.equinox.internal.provisional.p2.metadata.IArtifactKey;

/**
 * The main control point for the p2 garbage collector.  Takes a Profile and runs the CoreGarbageCollector with the
 * appropriate MarkSets for the repositories used by that Profile.
 * 
 * Takes the profile passed in and creates a set (markSet) that maps the artifact repositories it uses to the
 * artifact keys its IUs hold.  This is done by getting MarkSets from all registered IMarkSetProviders.
 * 
 * Then, the MarkSets are obtained for every other registered Profile in a similar fashion.  Each MarkSet is
 * checked to see if its artifact repository is already a key in markSet.  If so, that MarkSet's artifact keys 
 * are added to the list that is mapped to by the artifact repository. 
 */
public class GarbageCollector {
	private static final String ATTRIBUTE_CLASS = "class"; //$NON-NLS-1$
	private static final String PT_MARKSET = GCActivator.ID + ".marksetproviders"; //$NON-NLS-1$

	/**
	 * Maps IArtifactRepository objects to their respective "marked set" of IArtifactKeys
	 */
	private Map markSet;

	public void runGC(IProfile profile) {
		markSet = new HashMap();
		if (!traverseMainProfile(profile))
			return;

		//Complete each MarkSet with the MarkSets provided by all of the other registered Profiles
		traverseRegisteredProfiles();

		//Run the GC on each MarkSet
		invokeCoreGC();
	}

	private boolean traverseMainProfile(IProfile profile) {
		IExtensionRegistry registry = RegistryFactory.getRegistry();
		IConfigurationElement[] configElts = registry.getConfigurationElementsFor(PT_MARKSET);

		//First we collect all repos and keys for the profile being GC'ed
		for (int i = 0; i < configElts.length; i++) {
			if (!(configElts[i].getName().equals("run"))) { //$NON-NLS-1$
				continue;
			}
			IConfigurationElement runAttribute = configElts[i];
			if (runAttribute == null) {
				continue;
			}

			contributeMarkSets(runAttribute, profile, true);
		}
		return true;
	}

	private void invokeCoreGC() {
		Iterator keyIterator = markSet.keySet().iterator();
		while (keyIterator.hasNext()) {
			IArtifactRepository nextRepo = (IArtifactRepository) keyIterator.next();
			IArtifactKey[] keys = (IArtifactKey[]) ((Collection) markSet.get(nextRepo)).toArray(new IArtifactKey[0]);
			MarkSet aMarkSet = new MarkSet(keys, nextRepo);
			new CoreGarbageCollector().clean(aMarkSet.getKeys(), aMarkSet.getRepo());
		}
	}

	private void traverseRegisteredProfiles() {
		IExtensionRegistry registry = RegistryFactory.getRegistry();
		IConfigurationElement[] configElts = registry.getConfigurationElementsFor(PT_MARKSET);
		for (int i = 0; i < configElts.length; i++) {
			if (!(configElts[i].getName().equals("run"))) { //$NON-NLS-1$
				continue;
			}
			IConfigurationElement runAttribute = configElts[i];
			if (runAttribute == null) {
				continue;
			}

			IProfileRegistry profileRegistry = (IProfileRegistry) GCActivator.getService(GCActivator.getContext(), IProfileRegistry.class.getName());
			if (profileRegistry == null)
				return;
			IProfile[] registeredProfiles = profileRegistry.getProfiles();

			for (int j = 0; j < registeredProfiles.length; j++) {
				contributeMarkSets(runAttribute, registeredProfiles[j], false);
			}
		}
	}

	private class ParameterizedSafeRunnable implements ISafeRunnable {
		IConfigurationElement cfg;
		IProfile aProfile;
		MarkSet[] aProfileMarkSets;

		public ParameterizedSafeRunnable(IConfigurationElement runtAttribute, IProfile profile) {
			cfg = runtAttribute;
			aProfile = profile;
		}

		public void handleException(Throwable exception) {
			LogHelper.log(new Status(IStatus.ERROR, GCActivator.ID, Messages.Error_in_extension, exception));
		}

		public void run() throws Exception {
			IMarkSetProvider aMarkSetProvider = (IMarkSetProvider) cfg.createExecutableExtension(ATTRIBUTE_CLASS);
			if (aMarkSetProvider == null) {
				aProfileMarkSets = null;
				return;
			}
			aProfileMarkSets = aMarkSetProvider.getMarkSets(aProfile);
		}

		public MarkSet[] getResult() {
			return aProfileMarkSets;
		}
	}

	private void contributeMarkSets(IConfigurationElement runAttribute, IProfile profile, boolean addRepositories) {
		ParameterizedSafeRunnable providerExecutor = new ParameterizedSafeRunnable(runAttribute, profile);
		SafeRunner.run(providerExecutor);
		MarkSet[] aProfileMarkSets = providerExecutor.getResult();
		if (aProfileMarkSets[0] == null)
			return;

		for (int i = 0; i < aProfileMarkSets.length; i++) {
			if (aProfileMarkSets[i] == null) {
				continue;
			}

			for (int j = 0; j < aProfileMarkSets.length; j++) {
				if (aProfileMarkSets[j] == null) {
					continue;
				}
				Collection keys = (Collection) markSet.get(aProfileMarkSets[j].getRepo());
				if (keys == null) {
					if (addRepositories) {
						keys = new HashSet();
						markSet.put(aProfileMarkSets[j].getRepo(), keys);
						addKeys(keys, aProfileMarkSets[j].getKeys());
					}
				} else {
					addKeys(keys, aProfileMarkSets[j].getKeys());
				}
			}
		}
	}

	private void addKeys(Collection keyList, IArtifactKey[] keyArray) {
		for (int i = 0; i < keyArray.length; i++)
			keyList.add(keyArray[i]);
	}
}
