/*
 * $Header: /cvshome/build/org.osgi.util.mobile/src/org/osgi/util/mobile/UserPromptCondition.java,v 1.26 2006/07/10 08:18:30 pnagy Exp $
 *
 * Copyright (c) OSGi Alliance (2004, 2006). 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.util.mobile;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Dictionary;

import org.osgi.framework.Bundle;
import org.osgi.service.condpermadmin.Condition;
import org.osgi.service.condpermadmin.ConditionInfo;

/**
 * Class representing a user prompt condition. Instances of this class hold two
 * values: a prompt string that is to be displayed to the user and the
 * permission level string according to MIDP2.0 (oneshot, session, blanket).
 *  
 */
public class UserPromptCondition implements Condition {
	
	/*
	 * NOTE: An implementor may also choose to replace this class in
	 * their distribution with a class that directly interfaces with the
	 * policy implementation. This replacement class MUST NOT alter the
	 * public/protected signature of this class.
	 */
	// this will need to be set by the implementation class
	static Method factory = null;
	Condition realUserPromptCondition;

	private final Bundle bundle;
	private final String levels;
	private final String defaultLevel;
	private final String catalogName;
	private final String message;
	
	/**
	 * Returns a UserPromptCondition object with the given prompt string and permission
	 * level. The user should be given choice as to what level of permission is
	 * given. Thus, the lifetime of the permission is controlled by the user.
	 *
	 * @param bundle the bundle to ask about.
	 * @param conditionInfo the conditionInfo containing the construction information. Its 
	 * 			{@link ConditionInfo#getArgs()} method should return a String array with 4
	 * 			strings in it:
	 * <ol start="0">
	 * <li>the possible permission levels. This is a comma-separated list that can contain
	 * 		following strings: ONESHOT SESSION BLANKET. The order is not important. This
	 * 		parameter is case-insensitive.
	 * 		</li>
	 * <li>the default permission level, one chosen from the possible permission levels. If
	 * 		it is an empty string, then there is no default. This parameter
	 * 		is case-insensitive.</li>
	 * <li>the message catalog base name. It will be loaded by a {@link java.util.ResourceBundle},
	 * 		or equivalent
	 * 		from an exporting OSGi Bundle. Thus, if the catalogName is "com.provider.messages.userprompt",
	 * 		then there should be an OSGi Bundle exporting the "com.provider.messages" package, and inside
	 * 		it files like "userprompt_en_US.properties".</li>
	 * <li>textual description of the condition, to be displayed to the user. If
	 * 		it starts with a '%' sign, then the message is looked up from the catalog specified previously.
	 * 		The key is the rest of the string after the '%' sign.</li>
	 * </ol>
	 * @return The requested UserPromptCondition.
	 * @throws IllegalArgumentException if the parameters are malformed.
	 * @throws NullPointerException if one of the parameters is <code>null</code>.
	 */
	public static Condition getCondition(Bundle bundle,ConditionInfo conditionInfo)
	{
		String[] args = conditionInfo.getArgs();
		if (args==null) throw new NullPointerException("args");
		if (args.length!=4) throw new IllegalArgumentException("args.length=="+args.length+" (should be 4)");
		if (bundle==null) throw new NullPointerException("bundle");
		String levels = args[0];
		String defaultLevel = args[1];
		String catalogName = args[2];
		String message = args[3];
		if (levels==null) throw new NullPointerException("levels");
		if (defaultLevel==null) throw new NullPointerException("defaultLevel");
		if (catalogName==null) throw new NullPointerException("catalogName");
		if (message==null) throw new NullPointerException("message");
		
		if (factory==null) {
			// the bundle implementing the UserPromptCondition has not started yet.
			// Do wrapping magick.
			return new UserPromptCondition(bundle,levels,defaultLevel,catalogName,message);
		} else {
			// there is already a factory, no need to do any wrapping magic
			try {
				return (Condition) factory.invoke(null,new Object[]{bundle,levels,defaultLevel,catalogName,message});
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			} catch (InvocationTargetException e) {
				Throwable original = e.getTargetException();
				if (original instanceof NullPointerException) throw (NullPointerException) original;
				if (original instanceof IllegalArgumentException) throw (IllegalArgumentException) original;
				e.printStackTrace();
			}
			// the factory method is not working, fallback behavior:
			factory = null;
			return new UserPromptCondition(bundle,levels,defaultLevel,catalogName,message);
		}
	}

	/**
	 * Instances of the UserPromptCondition are simply store the construction parameters
	 * until a "real" UserPromptCondition is registered in setFactory(). At that point, it
	 * will delegate all calls there.
	 * @param unused this parameter is here so that ConditionalPermissionAdmin would not
	 * 		use this as the constructor instead of the getInstance
	 * @param bundle
	 * @param levels
	 * @param defaultLevel
	 * @param catalogName
	 * @param message
	 */
	private UserPromptCondition(Bundle bundle,String levels,String defaultLevel,String catalogName,String message) {
		this.bundle=bundle;
		this.levels=levels;
		this.defaultLevel=defaultLevel;
		this.catalogName=catalogName;
		this.message=message;
	}
	
	/**
	 * Check if a factory is registered, and if yes, create userprompt to delegate calls to.
	 */
	private void lookForImplementation() {
		if ((realUserPromptCondition==null)&&(factory!=null)) {
			try {
				realUserPromptCondition = (Condition) factory.invoke(null,new Object[]{bundle,levels,defaultLevel,catalogName,message});
				return;
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			} catch (InvocationTargetException e) {
				e.printStackTrace();
			}
			// only if the factory call fails with some invocation exception
			factory = null;
		}
	}
	
	/**
	 * Checks if the {@link #isSatisfied()} method needs to prompt the user, thus cannot
	 * give results instantly. 
	 * This depends on the permission level given in 
	 * {@link UserPromptCondition#getCondition(Bundle, ConditionInfo)}. 
	 * <ul>
	 * <li>ONESHOT - isPostponed always returns true. The user is prompted for question every time.</li>
	 * <li>SESSION - isPostponed returns true until the user decides either yes or no for the current session.</li>
	 * <li>BLANKET - isPostponed returns true until the user decides either always or never.</li>
	 * </ul>
	 * Regardless of the session level, the user is always given the option to reject the prompt
	 * permanently, as if BLANKET/never was chosen. In this case, the question is not postponed
	 * anymore, and {@link #isSatisfied()} returns false.<br/>
	 * If the system supports an separately accessible permission management GUI,
	 * that may reset the condition
	 * to its initial state.
	 * 
	 * @return True, if user interaction is needed.
	 */
	public boolean isPostponed() {
		lookForImplementation();
		if (realUserPromptCondition!=null) {
			return realUserPromptCondition.isPostponed();
		} else {
			return true;
		}
	}

	/**
	 * Checks whether the condition may change during the lifetime of the UserPromptCondition object.
	 * This depends on the permission level given in 
	 * {@link UserPromptCondition#getCondition(Bundle, ConditionInfo)}. 
	 * <ul>
	 * 	<li>ONESHOT - true</li>
	 *  <li>SESSION - true, if the application model's session lifetime is
	 *  		shorter than the UserPromptCondition object lifetime</li>
	 *  <li>BLANKET - false</li>
	 * </ul>
	 * If the system supports separately accessible permission management GUI,
	 * then this function may also return true for SESSION and BLANKET.
	 * 
	 * @return True, if the condition can change.
	 */
	public boolean isMutable() {
		lookForImplementation();
		if (realUserPromptCondition!=null) {
			return realUserPromptCondition.isMutable();
		} else {
			// since we don't know what the actual status is, we cannot say
			// "the condition cannot change anymore"
			return true;
		}
	}

	/**
	 * Displays the prompt string to
	 * the user and returns true if the user accepts. Depending on the
	 * amount of levels the condition is assigned to, the prompt may have
	 * multiple accept buttons and one of them can be selected by default (see
	 * default level parameter at {@link UserPromptCondition#getCondition(Bundle, ConditionInfo)}).
	 * It must always be possible for the user
	 * to stop further prompting of this question, even with ONESHOT and SESSION levels.
	 * In case of BLANKET
	 * and SESSION levels, it is possible that the user has already answered the question,
	 * in this case there will be no prompting, but immediate return with the previous answer.
	 * 
	 * @return True if the user accepts the prompt (or accepts any prompt in
	 *         case there are multiple permission levels).
	 */
	public boolean isSatisfied() {
		lookForImplementation();
		if (realUserPromptCondition!=null) {
			return realUserPromptCondition.isSatisfied();
		} else {
			// paranoid security option
			return false;
		}
	}

	/**
	 * Checks an array of UserPrompt conditions.
	 * 
	 * @param conds The array containing the UserPrompt conditions to evaluate.
	 * @param context Storage area for evaluation. The {@link org.osgi.service.condpermadmin.ConditionalPermissionAdmin}
	 * 		may evaluate a condition several times for one permission check, so this context
	 * 		will be used to store results of ONESHOT questions. This way asking the same question
	 * 		twice in a row can be avoided. If context is null, temporary results will not be stored.
	 * @return True, if all conditions are satisfied.
	 * @throws NullPointerException if conds is null.
	 */
	public boolean isSatisfied(Condition[] conds, Dictionary context) {
		lookForImplementation();
		if (realUserPromptCondition!=null) {
			return realUserPromptCondition.isSatisfied(conds,context);
		} else {
			// paranoid security option
			return false;
		}
	}
}
