/*
 * This file is part of Nuts Framework.
 * Copyright(C) 2009-2012 Nuts Develop Team.
 *
 * Nuts Framework is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License any later version.
 *
 * Nuts Framework is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Nuts Framework. If not, see <http://www.gnu.org/licenses/>.
 */
package nuts.exts.xwork2.util;

import nuts.exts.xwork2.PermissionValidator;

import java.util.Iterator;
import java.util.Locale;
import java.util.Map;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.ActionProxy;
import com.opensymphony.xwork2.TextProvider;
import com.opensymphony.xwork2.inject.Container;
import com.opensymphony.xwork2.util.ValueStack;

/**
 * ContextUtil
 */
@SuppressWarnings("unchecked")
public class ContextUtils {

	/**
	 * findValueInStack
	 * @param <T> value type
	 * @param valueStack value stack
	 * @param valueClass value class
	 * @return value
	 */
	public static <T> T findValueInStack(ValueStack valueStack, Class<T> valueClass) {
		if (valueStack == null) {
			return null;
		}

		for (Iterator iterator = valueStack.getRoot().iterator(); iterator.hasNext();) {
			Object o = iterator.next();
			if (o != null && valueClass.isAssignableFrom(o.getClass())) {
				return (T)o;
			}
		}
		return null;
	}

	/**
	 * findTextProviderInStack
	 * @param valueStack value stack
	 * @return TextProvider
	 */
	public static TextProvider findTextProviderInStack(ValueStack valueStack) {
		return findValueInStack(valueStack, TextProvider.class);
	}

	/**
	 * findPermissionValidatorInStack
	 * @param valueStack value stack
	 * @return TextProvider
	 */
	public static PermissionValidator findPermissionValidatorInStack(ValueStack valueStack) {
		return findValueInStack(valueStack, PermissionValidator.class);
	}

	/**
	 * get TextProvider
	 * @return TextProvider
	 */
	public static TextProvider getTextProvider() {
		ValueStack valueStack = getValueStack();
		if (valueStack == null) {
			return null;
		}
		return findTextProviderInStack(valueStack);
	}

	/**
	 * get PermissionValidator
	 * @return PermissionValidator
	 */
	public static PermissionValidator getPermissionValidator() {
		ValueStack valueStack = getValueStack();
		if (valueStack == null) {
			return null;
		}
		return findPermissionValidatorInStack(valueStack);
	}

	/**
	 * get Container
	 * @param stack value stack
	 * @return container
	 */
	public static Container getContainer(ValueStack stack) {
		return (Container)stack.getContext().get(ActionContext.CONTAINER);
	}
	
	/**
	 * get ActionContext
	 * @return ActionContext
	 */
	public static ActionContext getActionContext() {
		return ActionContext.getContext();
	}

	/**
	 * getApplication
	 * @return application map
	 */
	public static Map<String, Object> getApplication() {
		return getActionContext().getApplication();
	}

	/**
	 * getSession
	 * @return session map
	 */
	public static Map<String, Object> getSession() {
		return getActionContext().getSession();
	}

	/**
	 * getParameters
	 * @return parameter map
	 */
	public static Map<String, Object> getParameters() {
		return getActionContext().getParameters();
	}

	/**
	 * getRequest
	 * @return request map
	 */
	public static Map<String, Object> getRequest() {
		return (Map<String, Object>)ActionContext.getContext().get("request");
	}

	/**
	 * get value stack
	 * @return value stack
	 */
	public static ValueStack getValueStack() {
		ActionContext context = getActionContext();
		if (context == null) {
			return null;
		}
		return context.getValueStack();
	}

	/**
	 * get action invocation
	 * @return action invocation
	 */
	public static ActionInvocation getActionInvocation() {
		return getActionContext().getActionInvocation();
	}

	/**
	 * get action proxy
	 * @return action proxy
	 */
	public static ActionProxy getActionProxy() {
		return getActionInvocation().getProxy();
	}

	/**
	 * get namespace
	 * @return namespace
	 */
	public static String getNamespace() {
		return getActionProxy().getNamespace();
	}

	/**
	 * get action
	 * @return action
	 */
	public static Object getAction() {
		return getActionProxy().getAction();
	}

	/**
	 * get action name
	 * @return action name
	 */
	public static String getActionName() {
		return getActionProxy().getActionName();
	}

	/**
	 * get action method
	 * @return action method
	 */
	public static String getActionMethod() {
		return getActionProxy().getMethod();
	}

	/**
	 * get context locale
	 * @return locale
	 */
	public static Locale getLocale() {
		Locale locale = null;

		ActionContext context = getActionContext();
		if (context != null) {
			locale = (Locale)context.get(ActionContext.LOCALE);
		}

		if (locale == null) {
			locale = Locale.getDefault();
		}
		return locale;
	}

}
