/*******************************************************************************
 * Copyright (c) 2011, 2016 VMware Inc and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *   VMware Inc. - initial contribution
 *   IBM - bug fixes and enhancements
 *******************************************************************************/

package org.eclipse.equinox.internal.region;

import java.util.*;
import org.eclipse.equinox.region.RegionFilter;
import org.osgi.framework.*;
import org.osgi.framework.wiring.BundleCapability;
import org.osgi.framework.wiring.BundleRevision;

public final class StandardRegionFilter implements RegionFilter {
	final static Filter ALL;

	static {
		try {
			ALL = FrameworkUtil.createFilter("(|(!(all=*))(all=*))"); //$NON-NLS-1$
		} catch (InvalidSyntaxException e) {
			// should never happen!
			e.printStackTrace();
			throw new RuntimeException(e);
		}
	}

	private static final String BUNDLE_ID_ATTR = "id"; //$NON-NLS-1$
	private final Map<String, Collection<Filter>> filters;

	public StandardRegionFilter(Map<String, Collection<Filter>> filters) {
		if (filters == null) {
			throw new IllegalArgumentException("filters must not be null."); //$NON-NLS-1$
		}
		// must perform deep copy to avoid external changes
		this.filters = new HashMap<String, Collection<Filter>>((int) ((filters.size() / 0.75) + 1));
		for (Map.Entry<String, Collection<Filter>> namespace : filters.entrySet()) {
			Collection<Filter> namespaceFilters = new ArrayList<Filter>(namespace.getValue());
			this.filters.put(namespace.getKey(), namespaceFilters);
		}
	}

	public boolean isAllowed(Bundle bundle) {
		if (bundle == null) {
			return false;
		}
		HashMap<String, Object> attrs = new HashMap<String, Object>(4);
		String bsn = bundle.getSymbolicName();
		if (bsn != null) {
			attrs.put(VISIBLE_BUNDLE_NAMESPACE, bsn);
			attrs.put(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE, bsn);
		}
		attrs.put(org.osgi.framework.Constants.BUNDLE_VERSION_ATTRIBUTE, bundle.getVersion());
		attrs.put(BUNDLE_ID_ATTR, bundle.getBundleId());
		return isBundleAllowed(attrs);
	}

	public boolean isAllowed(BundleRevision bundle) {
		HashMap<String, Object> attrs = new HashMap<String, Object>(4);
		String bsn = bundle.getSymbolicName();
		if (bsn != null) {
			attrs.put(VISIBLE_BUNDLE_NAMESPACE, bsn);
			attrs.put(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE, bsn);
		}
		attrs.put(org.osgi.framework.Constants.BUNDLE_VERSION_ATTRIBUTE, bundle.getVersion());
		attrs.put(BUNDLE_ID_ATTR, getBundleId(bundle));
		return isBundleAllowed(attrs);
	}

	/**
	 * Determines whether this filter allows the bundle with the given attributes
	 * 
	 * @param bundleAttributes the bundle attributes
	 * @return <code>true</code> if the bundle is allowed and <code>false</code>otherwise
	 */
	private boolean isBundleAllowed(Map<String, ?> bundleAttributes) {
		return isAllowed(VISIBLE_BUNDLE_NAMESPACE, bundleAttributes);
	}

	private static boolean match(Collection<Filter> filters, Map<String, ?> attrs) {
		if (filters == null)
			return false;
		for (Filter filter : filters) {
			if (filter == ALL || filter.matches(attrs))
				return true;
		}
		return false;
	}

	private static boolean match(Collection<Filter> filters, ServiceReference<?> service) {
		if (filters == null)
			return false;
		for (Filter filter : filters) {
			if (filter == ALL || filter.match(service))
				return true;
		}
		return false;
	}

	public boolean isAllowed(ServiceReference<?> service) {
		if (match(filters.get(VISIBLE_OSGI_SERVICE_NAMESPACE), service))
			return true;
		return matchAll(VISIBLE_OSGI_SERVICE_NAMESPACE, service);
	}

	public boolean isAllowed(BundleCapability capability) {
		return isAllowed(capability.getNamespace(), capability.getAttributes());
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public boolean isAllowed(String namespace, Map<String, ?> attributes) {
		if (match(filters.get(namespace), attributes))
			return true;
		return matchAll(namespace, attributes);
	}

	@SuppressWarnings("deprecation")
	static final String[] serviceNamespaces = new String[] {VISIBLE_OSGI_SERVICE_NAMESPACE, VISIBLE_SERVICE_NAMESPACE};

	private boolean matchAll(final String namespace, final Map<String, ?> attributes) {
		Collection<Filter> allMatching = filters.get(VISIBLE_ALL_NAMESPACE);
		if (allMatching == null) {
			return false;
		}
		return match(allMatching, new AbstractMap<String, Object>() {
			@SuppressWarnings("deprecation")
			@Override
			public Object get(Object key) {
				if (RegionFilter.VISIBLE_ALL_NAMESPACE_ATTRIBUTE.equals(key)) {
					if (VISIBLE_SERVICE_NAMESPACE.equals(namespace) || VISIBLE_OSGI_SERVICE_NAMESPACE.equals(namespace)) {
						return serviceNamespaces;
					}
					return namespace;
				}
				return attributes.get(key);
			}

			@Override
			public Set<java.util.Map.Entry<String, Object>> entrySet() {
				throw new UnsupportedOperationException();
			}
		});
	}

	private boolean matchAll(final String namespace, final ServiceReference<?> service) {
		Collection<Filter> allMatching = filters.get(VISIBLE_ALL_NAMESPACE);
		if (allMatching == null) {
			return false;
		}
		return match(allMatching, new AbstractMap<String, Object>() {
			@SuppressWarnings("deprecation")
			@Override
			public Object get(Object key) {
				if (RegionFilter.VISIBLE_ALL_NAMESPACE_ATTRIBUTE.equals(key)) {
					if (VISIBLE_SERVICE_NAMESPACE.equals(namespace) || VISIBLE_OSGI_SERVICE_NAMESPACE.equals(namespace)) {
						return serviceNamespaces;
					}
					return namespace;
				}
				return service.getProperty((String) key);
			}

			@Override
			public Set<java.util.Map.Entry<String, Object>> entrySet() {
				throw new UnsupportedOperationException();
			}
		});
	}

	public Map<String, Collection<String>> getSharingPolicy() {
		Map<String, Collection<String>> result = new HashMap<String, Collection<String>>((int) ((filters.size() / 0.75) + 1));
		for (Map.Entry<String, Collection<Filter>> namespace : filters.entrySet()) {
			result.put(namespace.getKey(), getFilters(namespace.getValue()));
		}
		return result;
	}

	private static Collection<String> getFilters(Collection<Filter> filters) {
		Collection<String> result = new ArrayList<String>(filters.size());
		for (Filter filter : filters) {
			result.add(filter.toString());
		}
		return result;
	}

	public String toString() {
		return getSharingPolicy().toString();
	}

	private Long getBundleId(BundleRevision bundleRevision) {
		return EquinoxStateHelper.getBundleId(bundleRevision);
	}
}
