/*******************************************************************************
 * Copyright (c) 2003, 2004 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.framework.internal.core;

import java.util.*;

import org.eclipse.osgi.service.resolver.Version;

/**
 * The BundleRepository holds all installed Bundle object for the
 * Framework.  The BundleRepository is also used to mark and unmark
 * bundle dependancies.
 *
 * <p> 
 * This class is not synchronized.  Any access to the bundle
 * repository must be synchronized by the caller.
 */
public class BundleRepository {
	/** bundles by install order */
	private ArrayList bundlesByInstallOrder; //TODO It does not seems to me that the users of this really care for the ordering. If this is confirmed this can be remove 
	//and getBundles could either return an array (an array is preferable as one if the method calling method finally returns an array and the others do not care)

	/** bundles keyed by bundle Id */
	private KeyedHashSet bundlesById;

	/** bundles keyed by SymbolicName */
	private Hashtable bundlesBySymbolicName; //TODO Does this need to be synchronized

	/** PackageAdmin */
	private PackageAdminImpl packageAdmin;

	public BundleRepository(int initialCapacity, PackageAdminImpl packageAdmin) {
		bundlesByInstallOrder = new ArrayList(initialCapacity);
		bundlesById = new KeyedHashSet(initialCapacity, true);
		bundlesBySymbolicName = new Hashtable(initialCapacity);
		this.packageAdmin = packageAdmin;
	}

	/**
	 * Gets a list of bundles ordered by install order.
	 * @return List of bundles by install order.
	 */
	public List getBundles() {
		return bundlesByInstallOrder;
	}

	/**
	 * Gets a bundle by its bundle Id.
	 * @param bundleId
	 * @return
	 */
	public AbstractBundle getBundle(long bundleId) {
		Long key = new Long(bundleId);
		return (AbstractBundle) bundlesById.getByKey(key);
	}

	public AbstractBundle[] getBundles(String symbolicName) {
		return (AbstractBundle[]) bundlesBySymbolicName.get(symbolicName);
	}

	public AbstractBundle getBundle(String symbolicName, String version) {
		AbstractBundle[] bundles = (AbstractBundle[]) bundlesBySymbolicName.get(symbolicName);
		if (bundles != null) {
			Version ver = new Version(version);
			if (bundles.length > 0) {
				for (int i = 0; i < bundles.length; i++) {
					if (bundles[i].getVersion().matchQualifier(ver)) {
						return bundles[i];
					}
				}
			}
		}
		return null;
	}

	public void add(AbstractBundle bundle) {
		bundlesByInstallOrder.add(bundle);
		bundlesById.add(bundle);
		String symbolicName = bundle.getSymbolicName();
		if (symbolicName != null) {
			AbstractBundle[] bundles = (AbstractBundle[]) bundlesBySymbolicName.get(symbolicName);
			if (bundles == null) {
				// making the initial capacity on this 1 since it
				// should be rare that multiple version exist
				bundles = new AbstractBundle[1];
				bundles[0] = bundle;
				bundlesBySymbolicName.put(symbolicName, bundles);
				return;
			}

			ArrayList list = new ArrayList(bundles.length + 1);
			// find place to insert the bundle
			Version newVersion = bundle.getVersion();
			boolean added = false;
			for (int i = 0; i < bundles.length; i++) {
				AbstractBundle oldBundle = bundles[i];
				Version oldVersion = oldBundle.getVersion();
				if (!added && newVersion.matchGreaterOrEqualTo(oldVersion)) {
					added = true;
					list.add(bundle);
				}
				list.add(oldBundle);
			}
			if (!added) {
				list.add(bundle);
			}

			bundles = new AbstractBundle[list.size()];
			list.toArray(bundles);
			bundlesBySymbolicName.put(symbolicName, bundles);
		}
	}

	public boolean remove(AbstractBundle bundle) {
		// remove by bundle ID
		boolean found = bundlesById.remove(bundle);
		if (!found)
			return false;

		// remove by install order
		bundlesByInstallOrder.remove(bundle);
		// remove by symbolic name
		String symbolicName = bundle.getSymbolicName();
		if (symbolicName == null)
			return true;

		AbstractBundle[] bundles = (AbstractBundle[]) bundlesBySymbolicName.get(symbolicName);
		if (bundles == null)
			return true;

		// found some bundles with the global name.
		// remove all references to the specified bundle.
		int numRemoved = 0;
		for (int i = 0; i < bundles.length; i++) {
			if (bundle == bundles[i]) {
				numRemoved++;
				bundles[i] = null;
			}
		}
		if (numRemoved > 0) {
			if (bundles.length - numRemoved <= 0) {
				// no bundles left in the array remove the array from the hash
				bundlesBySymbolicName.remove(symbolicName);
			} else {
				// create a new array with the null entries removed.
				AbstractBundle[] newBundles = new AbstractBundle[bundles.length - numRemoved];
				int indexCnt = 0;
				for (int i = 0; i < bundles.length; i++) {
					if (bundles[i] != null) {
						newBundles[indexCnt] = bundles[i];
						indexCnt++;
					}
				}
				bundlesBySymbolicName.put(symbolicName, newBundles);
			}
		}

		return true;
	}

	public void removeAllBundles() {
		bundlesByInstallOrder.clear();
		bundlesById = new KeyedHashSet();
		bundlesBySymbolicName.clear();
	}

	public void markDependancies() {
		KeyedElement[] elements = bundlesById.elements();
		for (int i = 0; i < elements.length; i++) {
			if (elements[i] instanceof BundleHost) {
				((BundleHost) elements[i]).getLoaderProxy().markDependencies();
			}
		}
	}

	public void unMarkDependancies(BundleLoaderProxy user) {
		KeyedElement[] elements = bundlesById.elements();
		for (int i = 0; i < elements.length; i++) {
			if (elements[i] instanceof BundleHost) {
				BundleLoaderProxy loaderProxy = ((BundleHost) elements[i]).getLoaderProxy();
				loaderProxy.unMarkUsed(user);
			}
		}

		// look in removal pending
		int size = packageAdmin.removalPending.size();
		for (int i = 0; i < size; i++) {
			BundleLoaderProxy loaderProxy = (BundleLoaderProxy) packageAdmin.removalPending.elementAt(i);
			loaderProxy.unMarkUsed(user);
		}
		user.markedUsedDependencies = false;
	}
}