/*******************************************************************************
 * Copyright (c) 2013, 2015 VMware Inc. 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:
 *   VMware Inc. - initial contribution
 *******************************************************************************/

package org.eclipse.equinox.internal.region.hook;

import java.util.Collection;
import java.util.HashMap;
import org.eclipse.equinox.region.*;
import org.osgi.framework.*;
import org.osgi.framework.hooks.bundle.FindHook;

/**
 * {@link RegionBundleFindHook} manages the visibility of bundles across regions according to the {@link RegionDigraph}.
 * <p />
 * 
 * <strong>Concurrent Semantics</strong><br />
 * Thread safe.
 */
public final class RegionBundleFindHook implements FindHook {

	private final RegionDigraph regionDigraph;

	private final long hookImplID;

	public RegionBundleFindHook(RegionDigraph regionDigraph, long hookImplID) {
		this.regionDigraph = regionDigraph;
		this.hookImplID = hookImplID;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void find(BundleContext context, Collection<Bundle> bundles) {
		Bundle finderBundle = getBundle(context);
		if (finderBundle == null) {
			// invalid finder bundle; clear out result
			bundles.clear();
			return;
		}
		long bundleID = finderBundle.getBundleId();
		if (bundleID == 0 || bundleID == hookImplID) {
			// The system bundle and the hook impl bundle can see all bundles
			return;
		}

		Region finderRegion = this.regionDigraph.getRegion(finderBundle);
		RegionBundleFindHook.find(finderRegion, bundles);
	}

	static void find(Region finderRegion, Collection<Bundle> bundles) {
		if (finderRegion == null) {
			bundles.clear();
			return;
		}

		Visitor visitor = new Visitor(bundles);
		finderRegion.visitSubgraph(visitor);
		Collection<Bundle> allowed = visitor.getAllowed();

		bundles.retainAll(allowed);
	}

	static class Visitor extends RegionDigraphVisitorBase<Bundle> {

		Visitor(Collection<Bundle> candidates) {
			super(candidates);
		}

		/**
		 * {@inheritDoc}
		 */
		@Override
		protected boolean contains(Region region, Bundle candidate) {
			return region.contains(candidate);
		}

		/**
		 * {@inheritDoc}
		 */
		@Override
		protected boolean isAllowed(Bundle candidate, RegionFilter filter) {
			return filter.isAllowed(candidate) || isLifecycleAllowed(filter, candidate);
		}

		private boolean isLifecycleAllowed(RegionFilter filter, Bundle bundle) {
			HashMap<String, Object> attrs = new HashMap<String, Object>(4);
			String bsn = bundle.getSymbolicName();
			if (bsn != null) {
				attrs.put(RegionFilter.VISIBLE_BUNDLE_NAMESPACE, bsn);
				attrs.put(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE, bsn);
			}
			attrs.put(org.osgi.framework.Constants.BUNDLE_VERSION_ATTRIBUTE, bundle.getVersion());
			return filter.isAllowed(RegionFilter.VISIBLE_BUNDLE_LIFECYCLE_NAMESPACE, attrs);
		}
	}

	static Bundle getBundle(BundleContext context) {
		try {
			return context.getBundle();
		} catch (IllegalStateException e) {
			// happens if the context is invalid
			return null;
		}
	}
}
