/*******************************************************************************
 * 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.internal.resolver;

import java.util.*;
import org.eclipse.osgi.framework.debug.DebugOptions;
import org.eclipse.osgi.framework.internal.core.KeyedElement;
import org.eclipse.osgi.framework.internal.core.KeyedHashSet;
import org.eclipse.osgi.service.resolver.*;
import org.osgi.framework.Bundle;

public class StateImpl implements State {
	transient private Resolver resolver;
	transient private StateDeltaImpl changes;
	transient private Map listeners = new HashMap(11);
	transient private KeyedHashSet resolvedBundles = new KeyedHashSet();
	private boolean resolved = true;
	protected long timeStamp = System.currentTimeMillis();
	private KeyedHashSet bundleDescriptions = new KeyedHashSet(false);
	private StateObjectFactory factory;

	private static long cumulativeTime;

	protected StateImpl() {
		// to prevent extra-package instantiation 
	}

	public boolean addBundle(BundleDescription description) {
		if (description.getBundleId() < 0)
			throw new IllegalArgumentException("no id set");
		if (!basicAddBundle(description))
			return false;
		resolved = false;
		getDelta().recordBundleAdded((BundleDescriptionImpl) description);
		if (resolver != null)
			resolver.bundleAdded(description);
		return true;
	}

	public StateChangeEvent compare(State state) {
		throw new UnsupportedOperationException("not implemented"); //$NON-NLS-1$
	}

	public BundleDescription removeBundle(long bundleId) {
		BundleDescription toRemove = getBundle(bundleId);
		if (toRemove == null || !removeBundle(toRemove))
			return null;
		return toRemove;
	}

	public boolean removeBundle(BundleDescription toRemove) {
		if (!bundleDescriptions.remove((KeyedElement) toRemove))
			return false;
		resolved = false;
		getDelta().recordBundleRemoved((BundleDescriptionImpl) toRemove);
		if (resolver != null)
			resolver.bundleRemoved(toRemove);
		return true;
	}

	public StateDelta getChanges() {
		return getDelta();
	}

	private StateDeltaImpl getDelta() {
		if (changes == null)
			changes = getNewDelta();
		return changes;
	}

	private StateDeltaImpl getNewDelta() {
		return new StateDeltaImpl(this);
	}

	public BundleDescription[] getBundles(final String symbolicName) {
		final List bundles = new ArrayList();
		for (Iterator iter = bundleDescriptions.iterator(); iter.hasNext();) {
			BundleDescription bundle = (BundleDescription) iter.next();
			if (symbolicName.equals(bundle.getUniqueId()))
				bundles.add(bundle);
		}
		return (BundleDescription[]) bundles.toArray(new BundleDescription[bundles.size()]);
	}

	public BundleDescription[] getBundles() {
		return (BundleDescription[]) bundleDescriptions.elements(new BundleDescription[bundleDescriptions.size()]);
	}

	public BundleDescription getBundle(long id) {
		return (BundleDescription) bundleDescriptions.getByKey(new Long(id));
	}

	// TODO: this does not comply with the spec	
	public BundleDescription getBundle(String requiredUniqueId, Version requiredVersion) {
		BundleDescription[] bundles = getBundles();
		for (int i = 0; i < bundles.length; i++) {
			if (requiredUniqueId.equals(bundles[i].getUniqueId()) && bundles[i].getVersion().equals(requiredVersion))
				return bundles[i];
		}
		return null;
	}

	public long getTimeStamp() {
		return timeStamp;
	}

	public boolean isResolved() {
		return resolved || isEmpty();
	}

	public void resolveConstraint(VersionConstraint constraint, Version actualVersion, BundleDescription supplier) {
		VersionConstraintImpl modifiable = ((VersionConstraintImpl) constraint);
		if (modifiable.getActualVersion() != actualVersion || modifiable.getSupplier() != supplier) {
			modifiable.setActualVersion(actualVersion);
			modifiable.setSupplier(supplier);
			if (constraint instanceof BundleSpecification || constraint instanceof HostSpecification) {
				boolean optional = (constraint instanceof BundleSpecification) && ((BundleSpecification) constraint).isOptional();
				getDelta().recordConstraintResolved((BundleDescriptionImpl) constraint.getBundle(), optional);
			}
		}
	}

	public void resolveBundle(BundleDescription bundle, int status) {
		((BundleDescriptionImpl) bundle).setState(status);
		getDelta().recordBundleResolved((BundleDescriptionImpl) bundle, status);
		if (status == Bundle.RESOLVED)
			resolvedBundles.add((KeyedElement) bundle);
		else {
			// ensures no links are left 
			unresolveConstraints(bundle);
			// remove the bundle from the resolved pool
			resolvedBundles.remove((KeyedElement) bundle);
		}
	}

	private void unresolveConstraints(BundleDescription bundle) {
		HostSpecification host = bundle.getHost();
		if (host != null)
			((VersionConstraintImpl) host).unresolve();
		PackageSpecification[] packages = bundle.getPackages();
		for (int i = 0; i < packages.length; i++)
			((VersionConstraintImpl) packages[i]).unresolve();
		BundleSpecification[] requiredBundles = bundle.getRequiredBundles();
		for (int i = 0; i < requiredBundles.length; i++)
			((VersionConstraintImpl) requiredBundles[i]).unresolve();
	}

	public Resolver getResolver() {
		return resolver;
	}

	public void setResolver(Resolver newResolver) {
		if (resolver == newResolver)
			return;
		if (resolver != null) {
			Resolver oldResolver = resolver;
			resolver = null;
			oldResolver.setState(null);
		}
		resolver = newResolver;
		if (resolver == null)
			return;
		resolver.setState(this);
	}

	private StateDelta resolve(boolean incremental, BundleDescription[] reResolve) {
		if (resolver == null)
			throw new IllegalStateException("no resolver set"); //$NON-NLS-1$		
		long start = 0;
		if (StateManager.DEBUG_PLATFORM_ADMIN)
			start = System.currentTimeMillis();
		if (!incremental)
			flush();
		if (resolved && reResolve == null)
			return new StateDeltaImpl(this);
		if (reResolve != null)
			resolver.resolve(reResolve);
		else
			resolver.resolve();
		resolved = true;
		// TODO: need to fire events for listeners
		StateDelta savedChanges = changes == null ? new StateDeltaImpl(this) : changes;
		changes = new StateDeltaImpl(this);

		if (StateManager.DEBUG_PLATFORM_ADMIN) {
			cumulativeTime = cumulativeTime + (System.currentTimeMillis() - start);
			DebugOptions.getDefault().setOption("org.eclipse.core.runtime.adaptor/resolver/timing/value", Long.toString(cumulativeTime));
		}

		return savedChanges;
	}

	private void flush() {
		resolver.flush();
		resolved = false;
		if (resolvedBundles.isEmpty())
			return;
		for (Iterator iter = resolvedBundles.iterator(); iter.hasNext();) {
			BundleDescriptionImpl resolvedBundle = (BundleDescriptionImpl) iter.next();
			resolvedBundle.setState(0);
		}
		resolvedBundles.clear();
	}

	public StateDelta resolve() {
		return resolve(true, null);
	}

	public StateDelta resolve(boolean incremental) {
		return resolve(incremental, null);
	}

	public StateDelta resolve(BundleDescription[] reResolve) {
		return resolve(true, reResolve);
	}

	public void setOverrides(Object value) {
		throw new UnsupportedOperationException();
	}

	public BundleDescription[] getResolvedBundles() {
		return (BundleDescription[]) resolvedBundles.elements(new BundleDescription[resolvedBundles.size()]);
	}

	public void addStateChangeListener(StateChangeListener listener, int flags) {
		if (listeners.containsKey(listener))
			return;
		listeners.put(listener, new Integer(flags));
	}

	public void removeStateChangeListener(StateChangeListener listener) {
		listeners.remove(listener);
	}

	public boolean isEmpty() {
		return bundleDescriptions.isEmpty();
	}

	public void setResolved(boolean resolved) {
		this.resolved = resolved;
	}

	public boolean basicAddBundle(BundleDescription description) {
		((BundleDescriptionImpl) description).setContainingState(this);
		return bundleDescriptions.add((BundleDescriptionImpl) description);
	}

	void addResolvedBundle(BundleDescriptionImpl resolved) {
		resolvedBundles.add(resolved);
	}

	public PackageSpecification[] getExportedPackages() {
		final List allExportedPackages = new ArrayList();
		for (Iterator iter = resolvedBundles.iterator(); iter.hasNext();) {
			BundleDescription bundle = (BundleDescription) iter.next();
			PackageSpecification[] bundlePackages = bundle.getPackages();
			for (int i = 0; i < bundlePackages.length; i++)
				if (bundlePackages[i].isExported() && bundlePackages[i].getSupplier() == bundle)
					allExportedPackages.add(bundlePackages[i]);
		}
		return (PackageSpecification[]) allExportedPackages.toArray(new PackageSpecification[allExportedPackages.size()]);
	}

	public BundleDescription[] getImportingBundles(final PackageSpecification exportedPackage) {
		if (!exportedPackage.isResolved())
			return null;
		final List allImportingBundles = new ArrayList();
		for (Iterator iter = resolvedBundles.iterator(); iter.hasNext();) {
			BundleDescription bundle = (BundleDescription) iter.next();
			PackageSpecification[] bundlePackages = bundle.getPackages();
			for (int i = 0; i < bundlePackages.length; i++)
				if (bundlePackages[i].getName().equals(exportedPackage.getName()) && bundlePackages[i].getSupplier() == exportedPackage.getBundle()) {
					allImportingBundles.add(bundle);
					break;
				}
		}
		return (BundleDescription[]) allImportingBundles.toArray(new BundleDescription[allImportingBundles.size()]);
	}

	public BundleDescription[] getFragments(final BundleDescription host) {
		final List fragments = new ArrayList();
		for (Iterator iter = bundleDescriptions.iterator(); iter.hasNext();) {
			BundleDescription bundle = (BundleDescription) iter.next();
			HostSpecification hostSpec = bundle.getHost();
			if (hostSpec != null && hostSpec.getSupplier() == host)
				fragments.add(bundle);
		}
		return (BundleDescription[]) fragments.toArray(new BundleDescription[fragments.size()]);
	}

	public void setTimeStamp(long newTimeStamp) {
		timeStamp = newTimeStamp;
	}

	public StateObjectFactory getFactory() {
		return factory;
	}

	void setFactory(StateObjectFactory factory) {
		this.factory = factory;
	}
}