/*******************************************************************************
 * Copyright (c) 2012, 2017 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
 *******************************************************************************/
package org.eclipse.osgi.container;

import java.security.AllPermission;
import java.util.*;
import org.eclipse.osgi.internal.framework.FilterImpl;
import org.osgi.framework.*;
import org.osgi.framework.namespace.HostNamespace;
import org.osgi.resource.Namespace;

/**
 * A builder for creating module {@link ModuleRevision} objects.  A builder can only be used by 
 * the module {@link ModuleContainer container} to build revisions when 
 * {@link ModuleContainer#install(Module, String, ModuleRevisionBuilder, Object) 
 * installing} or {@link ModuleContainer#update(Module, ModuleRevisionBuilder, Object) updating} a module.
 * <p>
 * The builder provides the instructions to the container for creating a {@link ModuleRevision}.
 * They are not thread-safe; in the absence of external synchronization, they do not support concurrent access by multiple threads.
 * @since 3.10
 */
public final class ModuleRevisionBuilder {
	private final static Class<?> SINGLETON_MAP_CLASS = Collections.singletonMap(null, null).getClass();
	private final static Class<?> UNMODIFIABLE_MAP_CLASS = Collections.unmodifiableMap(Collections.emptyMap()).getClass();

	/**
	 * Provides information about a capability or requirement
	 */
	public static class GenericInfo {
		final String namespace;
		final Map<String, String> directives;
		final Map<String, Object> attributes;

		GenericInfo(String namespace, Map<String, String> directives, Map<String, Object> attributes) {
			this.namespace = namespace;
			this.directives = directives;
			this.attributes = attributes;
		}

		/**
		 * Returns the namespace of this generic info
		 * @return the namespace
		 */
		public String getNamespace() {
			return namespace;
		}

		/**
		 * Returns the directives of this generic info
		 * @return the directives
		 */
		public Map<String, String> getDirectives() {
			return directives;
		}

		/**
		 * Returns the attributes of this generic info
		 * @return the attributes
		 */
		public Map<String, Object> getAttributes() {
			return attributes;
		}
	}

	private String symbolicName = null;
	private Version version = Version.emptyVersion;
	private int types = 0;
	private final List<GenericInfo> capabilityInfos = new ArrayList<>();
	private final List<GenericInfo> requirementInfos = new ArrayList<>();
	private long id = -1;

	/**
	 * Constructs a new module builder
	 */
	public ModuleRevisionBuilder() {
		// nothing
	}

	/**
	 * Sets the symbolic name for the builder
	 * @param symbolicName the symbolic name
	 */
	public void setSymbolicName(String symbolicName) {
		this.symbolicName = symbolicName;
	}

	/**
	 * Sets the module version for the builder.
	 * @param version the version
	 */
	public void setVersion(Version version) {
		this.version = version;
	}

	/**
	 * Sets the module types for the builder.
	 * @param types the module types
	 */
	public void setTypes(int types) {
		this.types = types;
	}

	/**
	 * Sets the module ID for the builder.
	 * <p>
	 * This module ID will be used if this builder is used to
	 * {@link ModuleContainer#install(Module, String, ModuleRevisionBuilder, Object) install}
	 * a module.  If the ID is not set then a module ID will be generated by the module
	 * container at install time. If a module already exists with the specified ID
	 * then an error will occur when attempting to install a new module with this
	 * builder.
	 * <p>
	 * Note that the system module with location {@link Constants#SYSTEM_BUNDLE_LOCATION}
	 * always gets module ID of zero.  The builder for the system module is not
	 * asked to provide the module ID for the system module at install time.
	 * @param id the module ID to use.  Must be >= 1.
	 * @since 3.13
	 */
	public void setId(long id) {
		if (id < 1) {
			throw new IllegalArgumentException("ID must be >=1."); //$NON-NLS-1$
		}
		this.id = id;
	}

	void setInternalId(long id) {
		this.id = id;
	}

	/**
	 * Adds a capability to this builder using the specified namespace, directives and attributes
	 * @param namespace the namespace of the capability
	 * @param directives the directives of the capability
	 * @param attributes the attributes of the capability
	 */
	public void addCapability(String namespace, Map<String, String> directives, Map<String, Object> attributes) {
		addGenericInfo(capabilityInfos, namespace, directives, attributes);
	}

	/**
	 * Returns a snapshot of the capabilities for this builder
	 * @return the capabilities
	 */
	public List<GenericInfo> getCapabilities() {
		return new ArrayList<>(capabilityInfos);
	}

	/**
	 * Adds a requirement to this builder using the specified namespace, directives and attributes
	 * @param namespace the namespace of the requirement
	 * @param directives the directives of the requirement
	 * @param attributes the attributes of the requirement
	 */
	public void addRequirement(String namespace, Map<String, String> directives, Map<String, Object> attributes) {
		addGenericInfo(requirementInfos, namespace, directives, attributes);
	}

	/**
	 * Returns a snapshot of the requirements for this builder
	 * @return the requirements
	 */
	public List<GenericInfo> getRequirements() {
		return new ArrayList<>(requirementInfos);
	}

	/**
	 * Returns the symbolic name for this builder.
	 * @return the symbolic name for this builder.
	 */
	public String getSymbolicName() {
		return symbolicName;
	}

	/**
	 * Returns the module version for this builder.
	 * @return the module version for this builder.
	 */
	public Version getVersion() {
		return version;
	}

	/**
	 * Returns the module type for this builder.
	 * @return the module type for this builder.
	 */
	public int getTypes() {
		return types;
	}

	/**
	 * Returns the module id for this builder. A value of -1
	 * indicates that the module ID will be generated by the
	 * module container at {@link ModuleContainer#install(Module, String, ModuleRevisionBuilder, Object) install}
	 * time.
	 * @return the module id for this builder.
	 * @since 3.13
	 */
	public long getId() {
		return id;
	}

	/**
	 * Used by the container to build a new revision for a module.
	 * This builder is used to build a new {@link Module#getCurrentRevision() current}
	 * revision for the specified module.
	 * @param module the module to build a new revision for
	 * @param revisionInfo the revision info for the new revision, may be {@code null}
	 * @return the new new {@link Module#getCurrentRevision() current} revision.
	 */
	ModuleRevision addRevision(Module module, Object revisionInfo) {
		Collection<?> systemNames = Collections.emptyList();
		Module systemModule = module.getContainer().getModule(0);
		if (systemModule != null) {
			ModuleRevision systemRevision = systemModule.getCurrentRevision();
			List<ModuleCapability> hostCapabilities = systemRevision.getModuleCapabilities(HostNamespace.HOST_NAMESPACE);
			for (ModuleCapability hostCapability : hostCapabilities) {
				Object hostNames = hostCapability.getAttributes().get(HostNamespace.HOST_NAMESPACE);
				if (hostNames instanceof Collection) {
					systemNames = (Collection<?>) hostNames;
				} else if (hostNames instanceof String) {
					systemNames = Arrays.asList(hostNames);
				}
			}
		}
		ModuleRevisions revisions = module.getRevisions();
		ModuleRevision revision = new ModuleRevision(symbolicName, version, types, capabilityInfos, requirementInfos, revisions, revisionInfo);
		revisions.addRevision(revision);
		module.getContainer().getAdaptor().associateRevision(revision, revisionInfo);

		try {
			List<ModuleRequirement> hostRequirements = revision.getModuleRequirements(HostNamespace.HOST_NAMESPACE);
			for (ModuleRequirement hostRequirement : hostRequirements) {
				FilterImpl f = null;
				String filterSpec = hostRequirement.getDirectives().get(Namespace.REQUIREMENT_FILTER_DIRECTIVE);
				if (filterSpec != null) {
					try {
						f = FilterImpl.newInstance(filterSpec);
						String hostName = f.getPrimaryKeyValue(HostNamespace.HOST_NAMESPACE);
						if (hostName != null) {
							if (systemNames.contains(hostName)) {
								Bundle b = module.getBundle();
								if (b != null && !b.hasPermission(new AllPermission())) {
									SecurityException se = new SecurityException("Must have AllPermission granted to install an extension bundle"); //$NON-NLS-1$
									// TODO this is such a hack: making the cause a bundle exception so we can throw the right one later
									BundleException be = new BundleException(se.getMessage(), BundleException.SECURITY_ERROR, se);
									se.initCause(be);
									throw se;
								}
								module.getContainer().checkAdminPermission(module.getBundle(), AdminPermission.EXTENSIONLIFECYCLE);
							}
						}
					} catch (InvalidSyntaxException e) {
						continue;
					}
				}
			}
			module.getContainer().checkAdminPermission(module.getBundle(), AdminPermission.LIFECYCLE);
		} catch (SecurityException e) {
			revisions.removeRevision(revision);
			throw e;
		}
		return revision;
	}

	private static void addGenericInfo(List<GenericInfo> infos, String namespace, Map<String, String> directives, Map<String, Object> attributes) {
		if (infos == null) {
			infos = new ArrayList<>();
		}
		infos.add(new GenericInfo(namespace, copyUnmodifiableMap(directives), copyUnmodifiableMap(attributes)));
	}

	private static <K, V> Map<K, V> copyUnmodifiableMap(Map<K, V> map) {
		int size = map.size();
		if (size == 0) {
			return Collections.emptyMap();
		}
		if (size == 1) {
			Map.Entry<K, V> entry = map.entrySet().iterator().next();
			return Collections.singletonMap(entry.getKey(), entry.getValue());
		}
		return Collections.unmodifiableMap(new HashMap<>(map));
	}

	void basicAddCapability(String namespace, Map<String, String> directives, Map<String, Object> attributes) {
		basicAddGenericInfo(capabilityInfos, namespace, directives, attributes);
	}

	void basicAddRequirement(String namespace, Map<String, String> directives, Map<String, Object> attributes) {
		basicAddGenericInfo(requirementInfos, namespace, directives, attributes);
	}

	private static void basicAddGenericInfo(List<GenericInfo> infos, String namespace, Map<String, String> directives, Map<String, Object> attributes) {
		if (infos == null) {
			infos = new ArrayList<>();
		}
		infos.add(new GenericInfo(namespace, unmodifiableMap(directives), unmodifiableMap(attributes)));
	}

	@SuppressWarnings("unchecked")
	static <K, V> Map<K, V> unmodifiableMap(Map<? extends K, ? extends V> map) {
		int size = map.size();
		if (size == 0) {
			return Collections.emptyMap();
		}
		if (size == 1) {
			if (map.getClass() != SINGLETON_MAP_CLASS) {
				Map.Entry<? extends K, ? extends V> entry = map.entrySet().iterator().next();
				map = Collections.<K, V> singletonMap(entry.getKey(), entry.getValue());
			}
		} else {
			if (map.getClass() != UNMODIFIABLE_MAP_CLASS) {
				map = Collections.unmodifiableMap(map);
			}
		}
		return (Map<K, V>) map;
	}
}
