/*
 * Copyright (c) OSGi Alliance (2005, 2021). 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.service.condpermadmin;

import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Dictionary;
import java.util.Hashtable;
import org.osgi.framework.Bundle;
import org.osgi.framework.Filter;
import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.InvalidSyntaxException;

/**
 * Condition to test if the location of a bundle matches or does not match a
 * pattern. Since the bundle's location cannot be changed, this condition is
 * immutable.
 * 
 * <p>
 * Pattern matching is done according to the filter string matching rules.
 * 
 * @ThreadSafe
 * @author $Id$
 */
public class BundleLocationCondition {
	private static final String	CONDITION_TYPE	= "org.osgi.service.condpermadmin.BundleLocationCondition";

	/**
	 * Constructs a condition that tries to match the passed Bundle's location
	 * to the location pattern.
	 * 
	 * @param bundle The Bundle being evaluated.
	 * @param info The ConditionInfo from which to construct the condition. The
	 *        ConditionInfo must specify one or two arguments. The first
	 *        argument of the ConditionInfo specifies the location pattern
	 *        against which to match the bundle location. Matching is done
	 *        according to the filter string matching rules. Any '*' characters
	 *        in the first argument are used as wildcards when matching bundle
	 *        locations unless they are escaped with a '\' character. The
	 *        Condition is satisfied if the bundle location matches the pattern.
	 *        The second argument of the ConditionInfo is optional. If a second
	 *        argument is present and equal to "!", then the satisfaction of the
	 *        Condition is negated. That is, the Condition is satisfied if the
	 *        bundle location does NOT match the pattern. If the second argument
	 *        is present but does not equal "!", then the second argument is
	 *        ignored.
	 * @return Condition object for the requested condition.
	 */
	static public Condition getCondition(final Bundle bundle, final ConditionInfo info) {
		if (!CONDITION_TYPE.equals(info.getType()))
			throw new IllegalArgumentException("ConditionInfo must be of type \"" + CONDITION_TYPE + "\"");
		String[] args = info.getArgs();
		if (args.length != 1 && args.length != 2)
			throw new IllegalArgumentException("Illegal number of args: " + args.length);
		String bundleLocation = AccessController.doPrivileged((PrivilegedAction<String>) () -> bundle.getLocation());
		Filter filter = null;
		try {
			filter = FrameworkUtil.createFilter("(location=" + escapeLocation(args[0]) + ")");
		} catch (InvalidSyntaxException e) {
			// this should never happen, but just in case
			throw new RuntimeException("Invalid filter: " + e.getFilter(), e);
		}
		Dictionary<String, String> matchProps = new Hashtable<>(2);
		matchProps.put("location", bundleLocation);
		boolean negate = (args.length == 2) ? "!".equals(args[1]) : false;
		return (negate ^ filter.match(matchProps)) ? Condition.TRUE : Condition.FALSE;
	}

	private BundleLocationCondition() {
		// private constructor to prevent objects of this type
	}

	/**
	 * Escape the value string such that '(', ')' and '\' are escaped. The '\'
	 * char is only escaped if it is not followed by a '*'.
	 * 
	 * @param value unescaped value string.
	 * @return escaped value string.
	 */
	private static String escapeLocation(final String value) {
		boolean escaped = false;
		int inlen = value.length();
		int outlen = inlen << 1; /* inlen * 2 */

		char[] output = new char[outlen];
		value.getChars(0, inlen, output, inlen);

		int cursor = 0;
		for (int i = inlen; i < outlen; i++) {
			char c = output[i];
			switch (c) {
				case '\\' :
					if (i + 1 < outlen && output[i + 1] == '*')
						break;
				case '(' :
				case ')' :
					output[cursor] = '\\';
					cursor++;
					escaped = true;
					break;
			}

			output[cursor] = c;
			cursor++;
		}

		return escaped ? new String(output, 0, cursor) : value;
	}
}
