/*
 * Copyright (c) OSGi Alliance (2000, 2017). All Rights Reserved.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.osgi.framework;

import java.io.IOException;
import java.io.NotSerializableException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamField;
import java.security.AccessController;
import java.security.BasicPermission;
import java.security.Permission;
import java.security.PermissionCollection;
import java.security.PrivilegedAction;
import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * A bundle's authority to provide or require a capability.
 * <ul>
 * <li>The {@code provide} action allows a bundle to provide a capability
 * matching the specified filter.</li>
 * <li>The {@code require} action allows a bundle to require a capability
 * matching the specified filter.</li>
 * </ul>
 * 
 * @ThreadSafe
 * @author $Id$
 * @since 1.6
 */

public final class CapabilityPermission extends BasicPermission {
	static final long								serialVersionUID	= -7662148639076511574L;
	/**
	 * The action string {@code require}.
	 */
	public final static String						REQUIRE				= "require";
	/**
	 * The action string {@code provide}.
	 */
	public final static String						PROVIDE				= "provide";

	private final static int						ACTION_REQUIRE		= 0x00000001;
	private final static int						ACTION_PROVIDE		= 0x00000002;
	private final static int						ACTION_ALL			= ACTION_REQUIRE | ACTION_PROVIDE;
	final static int								ACTION_NONE			= 0;

	/**
	 * The actions mask.
	 */
	transient int									action_mask;

	/**
	 * The actions in canonical form.
	 * 
	 * @serial
	 */
	private volatile String							actions				= null;

	/**
	 * The attributes of the requested capability. Must be null if not
	 * constructed with attributes.
	 */
	transient final Map<String, Object>				attributes;

	/**
	 * The bundle of the requested capability. Must be null if not constructed
	 * with bundle.
	 */
	transient final Bundle							bundle;

	/**
	 * If this CapabilityPermission was constructed with a filter, this holds a
	 * Filter matching object used to evaluate the filter in implies.
	 */
	transient Filter								filter;

	/**
	 * This map holds the properties of the permission, used to match a filter
	 * in implies. This is not initialized until necessary, and then cached in
	 * this object.
	 */
	private transient volatile Map<String, Object>	properties;

	/**
	 * Create a new CapabilityPermission.
	 * 
	 * <p>
	 * The name is specified as a dot-separated string. Wildcards may be used.
	 * 
	 * <pre>
	 * name ::= &lt;namespace&gt; | &lt;namespace ending in &quot;.*&quot;&gt; | *
	 * </pre>
	 * 
	 * Examples:
	 * 
	 * <pre>
	 * com.acme.capability.*
	 * org.foo.capability
	 * *
	 * </pre>
	 * 
	 * For the {@code require} action, the name can also be a filter expression.
	 * The filter gives access to the capability attributes as well as the
	 * following attributes:
	 * <ul>
	 * <li>signer - A Distinguished Name chain used to sign the bundle providing
	 * the capability. Wildcards in a DN are not matched according to the filter
	 * string rules, but according to the rules defined for a DN chain.</li>
	 * <li>location - The location of the bundle providing the capability.</li>
	 * <li>id - The bundle ID of the bundle providing the capability.</li>
	 * <li>name - The symbolic name of the bundle providing the capability.</li>
	 * <li>capability.namespace - The namespace of the required capability.</li>
	 * </ul>
	 * Since the above attribute names may conflict with attribute names of a
	 * capability, you can prefix an attribute name with '@' in the filter
	 * expression to match against the capability attributes and not one of the
	 * above attributes. Filter attribute names are processed in a case
	 * sensitive manner.
	 * 
	 * <p>
	 * There are two possible actions: {@code require} and {@code provide}. The
	 * {@code require} permission allows the owner of this permission to require
	 * a capability matching the attributes. The {@code provide} permission
	 * allows the bundle to provide a capability in the specified capability
	 * namespace.
	 * 
	 * @param name The capability namespace or a filter over the attributes.
	 * @param actions {@code require},{@code provide} (canonical order)
	 * @throws IllegalArgumentException If the specified name is a filter
	 *         expression and either the specified action is not {@code require}
	 *         or the filter has an invalid syntax.
	 */
	public CapabilityPermission(String name, String actions) {
		this(name, parseActions(actions));
		if ((this.filter != null) && ((action_mask & ACTION_ALL) != ACTION_REQUIRE)) {
			throw new IllegalArgumentException("invalid action string for filter expression");
		}
	}

	/**
	 * Creates a new requested {@code CapabilityPermission} object to be used by
	 * code that must perform {@code checkPermission} for the {@code require}
	 * action. {@code CapabilityPermission} objects created with this
	 * constructor cannot be added to a {@code CapabilityPermission} permission
	 * collection.
	 * 
	 * @param namespace The requested capability namespace.
	 * @param attributes The requested capability attributes.
	 * @param providingBundle The bundle providing the requested capability.
	 * @param actions The action {@code require}.
	 * @throws IllegalArgumentException If the specified action is not
	 *         {@code require} or attributes or providingBundle are {@code null}
	 *         .
	 */
	public CapabilityPermission(String namespace, Map<String, ?> attributes, Bundle providingBundle, String actions) {
		super(namespace);
		setTransients(namespace, parseActions(actions));
		if (attributes == null) {
			throw new IllegalArgumentException("attributes must not be null");
		}
		if (providingBundle == null) {
			throw new IllegalArgumentException("bundle must not be null");
		}
		this.attributes = new HashMap<String, Object>(attributes);
		this.bundle = providingBundle;
		if ((action_mask & ACTION_ALL) != ACTION_REQUIRE) {
			throw new IllegalArgumentException("invalid action string");
		}
	}

	/**
	 * Package private constructor used by CapabilityPermissionCollection.
	 * 
	 * @param name class name
	 * @param mask action mask
	 */
	CapabilityPermission(String name, int mask) {
		super(name);
		setTransients(name, mask);
		this.attributes = null;
		this.bundle = null;
	}

	/**
	 * Called by constructors and when deserialized.
	 * 
	 * @param mask action mask
	 */
	private void setTransients(String name, int mask) {
		if ((mask == ACTION_NONE) || ((mask & ACTION_ALL) != mask)) {
			throw new IllegalArgumentException("invalid action string");
		}
		action_mask = mask;
		filter = parseFilter(name);
	}

	/**
	 * Parse action string into action mask.
	 * 
	 * @param actions Action string.
	 * @return action mask.
	 */
	private static int parseActions(String actions) {
		boolean seencomma = false;

		int mask = ACTION_NONE;

		if (actions == null) {
			return mask;
		}

		char[] a = actions.toCharArray();

		int i = a.length - 1;
		if (i < 0)
			return mask;

		while (i != -1) {
			char c;

			// skip whitespace
			while ((i != -1) && ((c = a[i]) == ' ' || c == '\r' || c == '\n' || c == '\f' || c == '\t'))
				i--;

			// check for the known strings
			int matchlen;

			if (i >= 6 && (a[i - 6] == 'r' || a[i - 6] == 'R')
					&& (a[i - 5] == 'e' || a[i - 5] == 'E')
					&& (a[i - 4] == 'q' || a[i - 4] == 'Q')
					&& (a[i - 3] == 'u' || a[i - 3] == 'U')
					&& (a[i - 2] == 'i' || a[i - 2] == 'I')
					&& (a[i - 1] == 'r' || a[i - 1] == 'R')
					&& (a[i] == 'e' || a[i] == 'E')) {
				matchlen = 7;
				mask |= ACTION_REQUIRE;
			} else
				if (i >= 6 && (a[i - 6] == 'p' || a[i - 6] == 'P')
						&& (a[i - 5] == 'r' || a[i - 5] == 'R')
						&& (a[i - 4] == 'o' || a[i - 4] == 'O')
						&& (a[i - 3] == 'v' || a[i - 3] == 'V')
						&& (a[i - 2] == 'i' || a[i - 2] == 'I')
						&& (a[i - 1] == 'd' || a[i - 1] == 'D')
						&& (a[i] == 'e' || a[i] == 'E')) {
					matchlen = 7;
					mask |= ACTION_PROVIDE;
				} else {
					// parse error
					throw new IllegalArgumentException("invalid permission: " + actions);
				}

			// make sure we didn't just match the tail of a word
			// like "ackbarfprovide". Also, skip to the comma.
			seencomma = false;
			while (i >= matchlen && !seencomma) {
				switch (a[i - matchlen]) {
					case ',' :
						seencomma = true;
						/* FALLTHROUGH */
					case ' ' :
					case '\r' :
					case '\n' :
					case '\f' :
					case '\t' :
						break;
					default :
						throw new IllegalArgumentException("invalid permission: " + actions);
				}
				i--;
			}

			// point i at the location of the comma minus one (or -1).
			i -= matchlen;
		}

		if (seencomma) {
			throw new IllegalArgumentException("invalid permission: " + actions);
		}

		return mask;
	}

	/**
	 * Parse filter string into a Filter object.
	 * 
	 * @param filterString The filter string to parse.
	 * @return a Filter for this bundle. If the specified filterString is not a
	 *         filter expression, then {@code null} is returned.
	 * @throws IllegalArgumentException If the filter syntax is invalid.
	 */
	private static Filter parseFilter(String filterString) {
		filterString = filterString.trim();
		if (filterString.charAt(0) != '(') {
			return null;
		}

		try {
			return FrameworkUtil.createFilter(filterString);
		} catch (InvalidSyntaxException e) {
			throw new IllegalArgumentException("invalid filter", e);
		}
	}

	/**
	 * Determines if a {@code CapabilityPermission} object "implies" the
	 * specified permission.
	 * 
	 * @param p The target permission to check.
	 * @return {@code true} if the specified permission is implied by this
	 *         object; {@code false} otherwise.
	 */
	@Override
	public boolean implies(Permission p) {
		if (!(p instanceof CapabilityPermission)) {
			return false;
		}
		CapabilityPermission requested = (CapabilityPermission) p;
		if (bundle != null) {
			return false;
		}
		// if requested permission has a filter, then it is an invalid argument
		if (requested.filter != null) {
			return false;
		}
		return implies0(requested, ACTION_NONE);
	}

	/**
	 * Internal implies method. Used by the implies and the permission
	 * collection implies methods.
	 * 
	 * @param requested The requested CapabilityPermission which has already be
	 *        validated as a proper argument. The requested CapabilityPermission
	 *        must not have a filter expression.
	 * @param effective The effective actions with which to start.
	 * @return {@code true} if the specified permission is implied by this
	 *         object; {@code false} otherwise.
	 */
	boolean implies0(CapabilityPermission requested, int effective) {
		/* check actions first - much faster */
		effective |= action_mask;
		final int desired = requested.action_mask;
		if ((effective & desired) != desired) {
			return false;
		}
		/* Get filter if any */
		Filter f = filter;
		if (f == null) {
			return super.implies(requested);
		}
		return f.matches(requested.getProperties());
	}

	/**
	 * Returns the canonical string representation of the actions. Always
	 * returns present actions in the following order: {@code require},
	 * {@code provide}.
	 * 
	 * @return The canonical string representation of the actions.
	 */
	@Override
	public String getActions() {
		String result = actions;
		if (result == null) {
			StringBuilder sb = new StringBuilder();
			boolean comma = false;

			int mask = action_mask;
			if ((mask & ACTION_REQUIRE) == ACTION_REQUIRE) {
				sb.append(REQUIRE);
				comma = true;
			}

			if ((mask & ACTION_PROVIDE) == ACTION_PROVIDE) {
				if (comma)
					sb.append(',');
				sb.append(PROVIDE);
			}

			actions = result = sb.toString();
		}

		return result;
	}

	/**
	 * Returns a new {@code PermissionCollection} object for storing
	 * {@code CapabilityPermission} objects.
	 * 
	 * @return A new {@code PermissionCollection} object suitable for storing
	 *         {@code CapabilityPermission} objects.
	 */
	@Override
	public PermissionCollection newPermissionCollection() {
		return new CapabilityPermissionCollection();
	}

	/**
	 * Determines the equality of two CapabilityPermission objects.
	 * 
	 * Checks that specified object has the same name and action as this
	 * {@code CapabilityPermission}.
	 * 
	 * @param obj The object to test for equality.
	 * @return true if obj is a {@code CapabilityPermission}, and has the same
	 *         name and actions as this {@code CapabilityPermission} object;
	 *         {@code false} otherwise.
	 */
	@Override
	public boolean equals(Object obj) {
		if (obj == this) {
			return true;
		}

		if (!(obj instanceof CapabilityPermission)) {
			return false;
		}

		CapabilityPermission cp = (CapabilityPermission) obj;

		return (action_mask == cp.action_mask) && getName().equals(cp.getName()) && ((attributes == cp.attributes) || ((attributes != null) && (attributes.equals(cp.attributes))))
				&& ((bundle == cp.bundle) || ((bundle != null) && bundle.equals(cp.bundle)));
	}

	/**
	 * Returns the hash code value for this object.
	 * 
	 * @return Hash code value for this object.
	 */
	@Override
	public int hashCode() {
		int h = 31 * 17 + getName().hashCode();
		h = 31 * h + getActions().hashCode();
		if (attributes != null) {
			h = 31 * h + attributes.hashCode();
		}
		if (bundle != null) {
			h = 31 * h + bundle.hashCode();
		}
		return h;
	}

	/**
	 * WriteObject is called to save the state of this permission to a stream.
	 * The actions are serialized, and the superclass takes care of the name.
	 */
	private synchronized void writeObject(java.io.ObjectOutputStream s) throws IOException {
		if (bundle != null) {
			throw new NotSerializableException("cannot serialize");
		}
		// Write out the actions. The superclass takes care of the name
		// call getActions to make sure actions field is initialized
		if (actions == null)
			getActions();
		s.defaultWriteObject();
	}

	/**
	 * readObject is called to restore the state of this permission from a
	 * stream.
	 */
	private synchronized void readObject(java.io.ObjectInputStream s) throws IOException, ClassNotFoundException {
		// Read in the action, then initialize the rest
		s.defaultReadObject();
		setTransients(getName(), parseActions(actions));
	}

	/**
	 * Called by {@link CapabilityPermission#implies(Permission)}. This method
	 * is only called on a requested permission which cannot have a filter set.
	 * 
	 * @return a map of properties for this permission.
	 */
	private Map<String, Object> getProperties() {
		Map<String, Object> result = properties;
		if (result != null) {
			return result;
		}
		final Map<String, Object> props = new HashMap<String, Object>(5);
		props.put("capability.namespace", getName());
		if (bundle == null) {
			return properties = props;
		}
		AccessController.doPrivileged(new PrivilegedAction<Void>() {
			@Override
			public Void run() {
				props.put("id", Long.valueOf(bundle.getBundleId()));
				props.put("location", bundle.getLocation());
				String name = bundle.getSymbolicName();
				if (name != null) {
					props.put("name", name);
				}
				SignerProperty signer = new SignerProperty(bundle);
				if (signer.isBundleSigned()) {
					props.put("signer", signer);
				}
				return null;
			}
		});
		return properties = new Properties(props, attributes);
	}

	static private final class Properties extends AbstractMap<String, Object> {
		private final Map<String, Object>							properties;
		private final Map<String, Object>							attributes;
		private transient volatile Set<Map.Entry<String, Object>>	entries;

		Properties(Map<String, Object> properties, Map<String, Object> attributes) {
			this.properties = properties;
			this.attributes = attributes;
			entries = null;
		}

		@Override
		public Object get(Object k) {
			if (!(k instanceof String)) {
				return null;
			}
			String key = (String) k;
			if (key.charAt(0) == '@') {
				return attributes.get(key.substring(1));
			}
			Object value = properties.get(key);
			if (value != null) { // fall back to service properties
				return value;
			}
			return attributes.get(key);
		}

		@Override
		public Set<Map.Entry<String, Object>> entrySet() {
			if (entries != null) {
				return entries;
			}
			Set<Map.Entry<String, Object>> all = new HashSet<Map.Entry<String, Object>>(attributes.size() + properties.size());
			all.addAll(attributes.entrySet());
			all.addAll(properties.entrySet());
			return entries = Collections.unmodifiableSet(all);
		}
	}
}

/**
 * Stores a set of CapabilityPermission permissions.
 * 
 * @see java.security.Permission
 * @see java.security.Permissions
 * @see java.security.PermissionCollection
 */
final class CapabilityPermissionCollection extends PermissionCollection {
	static final long							serialVersionUID	= -615322242639008920L;

	/**
	 * Table of permissions.
	 * 
	 * @serial
	 * @GuardedBy this
	 */
	private Map<String, CapabilityPermission>	permissions;

	/**
	 * Boolean saying if "*" is in the collection.
	 * 
	 * @serial
	 * @GuardedBy this
	 */
	private boolean								all_allowed;

	/**
	 * Table of permissions with filter expressions.
	 * 
	 * @serial
	 * @GuardedBy this
	 */
	private Map<String, CapabilityPermission>	filterPermissions;

	/**
	 * Creates an empty CapabilityPermissionCollection object.
	 */
	public CapabilityPermissionCollection() {
		permissions = new HashMap<String, CapabilityPermission>();
		all_allowed = false;
	}

	/**
	 * Adds a permission to this permission collection.
	 * 
	 * @param permission The Permission object to add.
	 * @throws IllegalArgumentException If the specified permission is not a
	 *         CapabilityPermission object.
	 * @throws SecurityException If this {@code CapabilityPermissionCollection}
	 *         object has been marked read-only.
	 */
	@Override
	public void add(final Permission permission) {
		if (!(permission instanceof CapabilityPermission)) {
			throw new IllegalArgumentException("invalid permission: " + permission);
		}
		if (isReadOnly()) {
			throw new SecurityException("attempt to add a Permission to a " + "readonly PermissionCollection");
		}

		final CapabilityPermission cp = (CapabilityPermission) permission;
		if (cp.bundle != null) {
			throw new IllegalArgumentException("cannot add to collection: " + cp);
		}

		final String name = cp.getName();
		final Filter f = cp.filter;
		synchronized (this) {
			/* select the bucket for the permission */
			Map<String, CapabilityPermission> pc;
			if (f != null) {
				pc = filterPermissions;
				if (pc == null) {
					filterPermissions = pc = new HashMap<String, CapabilityPermission>();
				}
			} else {
				pc = permissions;
			}
			final CapabilityPermission existing = pc.get(name);

			if (existing != null) {
				final int oldMask = existing.action_mask;
				final int newMask = cp.action_mask;
				if (oldMask != newMask) {
					pc.put(name, new CapabilityPermission(name, oldMask | newMask));
				}
			} else {
				pc.put(name, cp);
			}

			if (!all_allowed) {
				if (name.equals("*")) {
					all_allowed = true;
				}
			}
		}
	}

	/**
	 * Determines if a set of permissions implies the permissions expressed in
	 * {@code permission}.
	 * 
	 * @param permission The Permission object to compare.
	 * @return {@code true} if {@code permission} is a proper subset of a
	 *         permission in the set; {@code false} otherwise.
	 */
	@Override
	public boolean implies(final Permission permission) {
		if (!(permission instanceof CapabilityPermission)) {
			return false;
		}
		final CapabilityPermission requested = (CapabilityPermission) permission;
		/* if requested permission has a filter, then it is an invalid argument */
		if (requested.filter != null) {
			return false;
		}

		String requestedName = requested.getName();
		final int desired = requested.action_mask;
		int effective = CapabilityPermission.ACTION_NONE;

		Collection<CapabilityPermission> perms;
		synchronized (this) {
			Map<String, CapabilityPermission> pc = permissions;
			CapabilityPermission cp;
			/* short circuit if the "*" Permission was added */
			if (all_allowed) {
				cp = pc.get("*");
				if (cp != null) {
					effective |= cp.action_mask;
					if ((effective & desired) == desired) {
						return true;
					}
				}
			}

			/*
			 * strategy: Check for full match first. Then work our way up the
			 * name looking for matches on a.b.*
			 */
			cp = pc.get(requestedName);
			if (cp != null) {
				/* we have a direct hit! */
				effective |= cp.action_mask;
				if ((effective & desired) == desired) {
					return true;
				}
			}
			/* work our way up the tree... */
			int last;
			int offset = requestedName.length() - 1;
			while ((last = requestedName.lastIndexOf(".", offset)) != -1) {
				requestedName = requestedName.substring(0, last + 1) + "*";
				cp = pc.get(requestedName);
				if (cp != null) {
					effective |= cp.action_mask;
					if ((effective & desired) == desired) {
						return true;
					}
				}
				offset = last - 1;
			}
			/*
			 * we don't have to check for "*" as it was already checked before
			 * we were called.
			 */
			pc = filterPermissions;
			if (pc == null) {
				return false;
			}
			perms = pc.values();
		}
		/* iterate one by one over filteredPermissions */
		for (CapabilityPermission perm : perms) {
			if (perm.implies0(requested, effective)) {
				return true;
			}
		}
		return false;
	}

	/**
	 * Returns an enumeration of all the {@code CapabilityPermission} objects in
	 * the container.
	 * 
	 * @return Enumeration of all the CapabilityPermission objects.
	 */
	@Override
	public synchronized Enumeration<Permission> elements() {
		List<Permission> all = new ArrayList<Permission>(permissions.values());
		Map<String, CapabilityPermission> pc = filterPermissions;
		if (pc != null) {
			all.addAll(pc.values());
		}
		return Collections.enumeration(all);
	}

	/* serialization logic */
	private static final ObjectStreamField[]	serialPersistentFields	= {new ObjectStreamField("permissions", HashMap.class), new ObjectStreamField("all_allowed", Boolean.TYPE),
			new ObjectStreamField("filterPermissions", HashMap.class)	};

	private synchronized void writeObject(ObjectOutputStream out) throws IOException {
		ObjectOutputStream.PutField pfields = out.putFields();
		pfields.put("permissions", permissions);
		pfields.put("all_allowed", all_allowed);
		pfields.put("filterPermissions", filterPermissions);
		out.writeFields();
	}

	private synchronized void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
		ObjectInputStream.GetField gfields = in.readFields();
		@SuppressWarnings("unchecked")
		HashMap<String, CapabilityPermission> p = (HashMap<String, CapabilityPermission>) gfields.get("permissions", null);
		permissions = p;
		all_allowed = gfields.get("all_allowed", false);
		@SuppressWarnings("unchecked")
		HashMap<String, CapabilityPermission> fp = (HashMap<String, CapabilityPermission>) gfields.get("filterPermissions", null);
		filterPermissions = fp;
	}
}
