/*******************************************************************************
 * Copyright (c) 2003, 2016 IBM Corporation 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:
 *     IBM Corporation - initial API and implementation
 *     Danail Nachev -  ProSyst - bug 218625
 *     Rob Harrop - SpringSource Inc. (bug 247522)
 *******************************************************************************/
package org.eclipse.osgi.internal.resolver;

import java.util.*;
import org.eclipse.osgi.internal.framework.EquinoxContainer;
import org.eclipse.osgi.service.resolver.*;
import org.osgi.framework.Constants;
import org.osgi.framework.wiring.BundleRevision;

public class ImportPackageSpecificationImpl extends VersionConstraintImpl implements ImportPackageSpecification {
	private String resolution = ImportPackageSpecification.RESOLUTION_STATIC; // the default is static
	private String symbolicName;
	private VersionRange bundleVersionRange;
	private Map<String, Object> attributes;
	private Map<String, String> arbitraryDirectives;

	public Map<String, Object> getDirectives() {
		synchronized (this.monitor) {
			Map<String, Object> result = new HashMap<>(5);
			if (resolution != null)
				result.put(Constants.RESOLUTION_DIRECTIVE, resolution);
			return result;
		}
	}

	public Object getDirective(String key) {
		synchronized (this.monitor) {
			if (key.equals(Constants.RESOLUTION_DIRECTIVE))
				return resolution;
			return null;
		}
	}

	Object setDirective(String key, Object value) {
		synchronized (this.monitor) {
			if (key.equals(Constants.RESOLUTION_DIRECTIVE))
				return resolution = (String) value;
			return null;
		}
	}

	void setDirectives(Map<String, ?> directives) {
		synchronized (this.monitor) {
			if (directives == null)
				return;
			resolution = (String) directives.get(Constants.RESOLUTION_DIRECTIVE);
		}
	}

	@SuppressWarnings("unchecked")
	void setArbitraryDirectives(Map<String, ?> directives) {
		synchronized (this.monitor) {
			this.arbitraryDirectives = (Map<String, String>) directives;
		}
	}

	Map<String, String> getArbitraryDirectives() {
		synchronized (this.monitor) {
			return arbitraryDirectives;
		}
	}

	public String getBundleSymbolicName() {
		synchronized (this.monitor) {
			if (Constants.SYSTEM_BUNDLE_SYMBOLICNAME.equals(symbolicName)) {
				StateImpl state = (StateImpl) getBundle().getContainingState();
				return state == null ? EquinoxContainer.NAME : state.getSystemBundle();
			}
			return symbolicName;
		}
	}

	public VersionRange getBundleVersionRange() {
		synchronized (this.monitor) {
			if (bundleVersionRange == null)
				return VersionRange.emptyRange;
			return bundleVersionRange;
		}
	}

	public Map<String, Object> getAttributes() {
		synchronized (this.monitor) {
			return attributes;
		}
	}

	@Override
	public boolean isSatisfiedBy(BaseDescription supplier) {
		return isSatisfiedBy(supplier, true);
	}

	public boolean isSatisfiedBy(BaseDescription supplier, boolean checkEE) {
		if (!(supplier instanceof ExportPackageDescription))
			return false;
		ExportPackageDescriptionImpl pkgDes = (ExportPackageDescriptionImpl) supplier;

		// If we are in strict mode, check to see if the export specifies friends.
		// If it does, are we one of the friends 
		String[] friends = (String[]) pkgDes.getDirective(StateImpl.FRIENDS_DIRECTIVE);
		Boolean internal = (Boolean) pkgDes.getDirective(StateImpl.INTERNAL_DIRECTIVE);
		if (internal.booleanValue() || friends != null) {
			StateImpl state = (StateImpl) getBundle().getContainingState();
			boolean strict = state == null ? false : state.inStrictMode();
			if (strict) {
				if (internal.booleanValue())
					return false;
				boolean found = false;
				if (friends != null && getBundle().getSymbolicName() != null)
					for (String friend : friends) {
						if (getBundle().getSymbolicName().equals(friend)) {
							found = true;
						}
					}
				if (!found)
					return false;
			}
		}
		String exporterSymbolicName = getBundleSymbolicName();
		if (exporterSymbolicName != null) {
			BundleDescription exporter = pkgDes.getExporter();
			if (!exporterSymbolicName.equals(exporter.getSymbolicName()))
				return false;
			if (getBundleVersionRange() != null && !getBundleVersionRange().isIncluded(exporter.getVersion()))
				return false;
		}

		String name = getName();
		// shortcut '*'
		// NOTE: wildcards are supported only in cases where this is a dynamic import
		if (!"*".equals(name) && !(name.endsWith(".*") && pkgDes.getName().startsWith(name.substring(0, name.length() - 1))) && !pkgDes.getName().equals(name)) //$NON-NLS-1$ //$NON-NLS-2$
			return false;
		if (getVersionRange() != null && !getVersionRange().isIncluded(pkgDes.getVersion()))
			return false;

		Map<String, ?> importAttrs = getAttributes();
		if (importAttrs != null) {
			Map<String, ?> exportAttrs = pkgDes.getAttributes();
			if (exportAttrs == null)
				return false;
			for (String importKey : importAttrs.keySet()) {
				Object importValue = importAttrs.get(importKey);
				Object exportValue = exportAttrs.get(importKey);
				if (exportValue == null || !importValue.equals(exportValue))
					return false;
			}
		}
		String[] mandatory = (String[]) pkgDes.getDirective(Constants.MANDATORY_DIRECTIVE);
		if (!hasMandatoryAttributes(mandatory))
			return false;
		// finally check the ee index
		if (!checkEE)
			return true;
		if (((BundleDescriptionImpl) getBundle()).getEquinoxEE() < 0)
			return true;
		int eeIndex = ((Integer) pkgDes.getDirective(ExportPackageDescriptionImpl.EQUINOX_EE)).intValue();
		return eeIndex < 0 || eeIndex == ((BundleDescriptionImpl) getBundle()).getEquinoxEE();
	}

	@Override
	protected boolean hasMandatoryAttributes(String[] checkMandatory) {
		if (checkMandatory != null) {
			Map<String, ?> importAttrs = getAttributes();
			for (String mandatory : checkMandatory) {
				if (Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE.equals(mandatory)) {
					if (getBundleSymbolicName() == null)
						return false;
				} else if (Constants.BUNDLE_VERSION_ATTRIBUTE.equals(mandatory)) {
					if (bundleVersionRange == null)
						return false;
				} else if (Constants.PACKAGE_SPECIFICATION_VERSION.equals(mandatory) || Constants.VERSION_ATTRIBUTE.equals(mandatory)) {
					if (getVersionRange() == null)
						return false;
				} else { // arbitrary attribute
					if (importAttrs == null)
						return false;
					if (importAttrs.get(mandatory) == null) {
						return false;
					}
				}
			}
		}
		return true;
	}

	protected void setBundleSymbolicName(String symbolicName) {
		synchronized (this.monitor) {
			this.symbolicName = symbolicName;
		}
	}

	protected void setBundleVersionRange(VersionRange bundleVersionRange) {
		synchronized (this.monitor) {
			this.bundleVersionRange = bundleVersionRange;
		}
	}

	@SuppressWarnings("unchecked")
	protected void setAttributes(Map<String, ?> attributes) {
		synchronized (this.monitor) {
			this.attributes = (Map<String, Object>) attributes;
		}
	}

	@Override
	public String toString() {
		return "Import-Package: " + getName() + "; version=\"" + getVersionRange() + "\""; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
	}

	@Override
	protected Map<String, String> getInternalDirectives() {
		synchronized (this.monitor) {
			Map<String, String> result = new HashMap<>(5);
			if (arbitraryDirectives != null)
				result.putAll(arbitraryDirectives);
			if (resolution != null) {
				if (ImportPackageSpecification.RESOLUTION_STATIC.equals(resolution))
					result.put(Constants.RESOLUTION_DIRECTIVE, Constants.RESOLUTION_MANDATORY);
				else
					result.put(Constants.RESOLUTION_DIRECTIVE, resolution);
			}
			result.put(Constants.FILTER_DIRECTIVE, createFilterDirective());
			return result;
		}
	}

	private String createFilterDirective() {
		StringBuffer filter = new StringBuffer();
		filter.append("(&"); //$NON-NLS-1$
		synchronized (this.monitor) {
			addFilterAttribute(filter, BundleRevision.PACKAGE_NAMESPACE, getName(), false);
			VersionRange range = getVersionRange();
			if (range != null && range != VersionRange.emptyRange)
				addFilterAttribute(filter, Constants.VERSION_ATTRIBUTE, range);
			if (symbolicName != null)
				addFilterAttribute(filter, Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE, symbolicName);
			if (bundleVersionRange != null)
				addFilterAttribute(filter, Constants.BUNDLE_VERSION_ATTRIBUTE, bundleVersionRange);
			if (attributes != null)
				addFilterAttributes(filter, attributes);
		}
		filter.append(')');
		return filter.toString();
	}

	@Override
	protected Map<String, Object> getInteralAttributes() {
		return Collections.<String, Object> emptyMap();
	}

	@Override
	protected String getInternalNameSpace() {
		return BundleRevision.PACKAGE_NAMESPACE;
	}
}
