/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.apache.struts2.components;

import com.opensymphony.xwork2.ObjectFactory;
import com.opensymphony.xwork2.config.Configuration;
import com.opensymphony.xwork2.config.RuntimeConfiguration;
import com.opensymphony.xwork2.config.entities.ActionConfig;
import com.opensymphony.xwork2.config.entities.InterceptorMapping;
import com.opensymphony.xwork2.inject.Inject;
import com.opensymphony.xwork2.interceptor.MethodFilterInterceptorUtil;
import com.opensymphony.xwork2.util.ValueStack;
import com.opensymphony.xwork2.validator.*;
import com.opensymphony.xwork2.validator.validators.VisitorFieldValidator;
import org.apache.commons.lang3.StringUtils;
import org.apache.struts2.dispatcher.mapper.ActionMapping;
import org.apache.struts2.views.annotations.StrutsTag;
import org.apache.struts2.views.annotations.StrutsTagAttribute;
import org.apache.struts2.views.jsp.TagUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;

/**
 * <!-- START SNIPPET: javadoc -->
 * <p>
 * Renders HTML an input form.
 * </p>
 *
 * <p>
 * The remote form allows the form to be submitted without the page being refreshed. The results from the form
 * can be inserted into any HTML element on the page.
 * </p>
 * <p>
 * NOTE:<br>
 * The order / logic in determining the posting url of the generated HTML form is as follows:
 * </p>
 *
 * <ol>
 * <li>
 * If the action attribute is not specified, then the current request will be used to
 * determine the posting url
 * </li>
 * <li>
 * If the action is given, Struts will try to obtain an ActionConfig. This will be
 * successful if the action attribute is a valid action alias defined struts.xml.
 * </li>
 * <li>
 * If the action is given and is not an action alias defined in struts.xml, Struts
 * will used the action attribute as if it is the posting url, separting the namespace
 * from it and using UrlHelper to generate the final url.
 * </li>
 * </ol>
 *
 * <!-- END SNIPPET: javadoc -->
 *
 * <p><b>Examples</b></p>
 *
 * <pre>
 * <!-- START SNIPPET: example -->
 *
 * &lt;s:form ... /&gt;
 *
 * <!-- END SNIPPET: example -->
 * </pre>
 *
 */
@StrutsTag(
    name="form",
    tldTagClass="org.apache.struts2.views.jsp.ui.FormTag",
    description="Renders an input form",
    allowDynamicAttributes=true)
public class Form extends ClosingUIBean {
    public static final String OPEN_TEMPLATE = "form";
    public static final String TEMPLATE = "form-close";

    private int sequence = 0;

    protected String onsubmit;
    protected String onreset;
    protected String action;
    protected String target;
    protected String enctype;
    protected String method;
    protected String namespace;
    protected String validate;
    protected String portletMode;
    protected String windowState;
    protected String acceptcharset;
    protected boolean includeContext = true;

    protected String focusElement;
    protected Configuration configuration;
    protected ObjectFactory objectFactory;
    protected UrlRenderer urlRenderer;
    protected ActionValidatorManager actionValidatorManager;

    public Form(ValueStack stack, HttpServletRequest request, HttpServletResponse response) {
        super(stack, request, response);
    }

    @Override
    protected boolean evaluateNameValue() {
        return false;
    }

    @Override
    public String getDefaultOpenTemplate() {
        return OPEN_TEMPLATE;
    }

    @Override
    protected String getDefaultTemplate() {
        return TEMPLATE;
    }

    @Inject
    public void setConfiguration(Configuration configuration) {
        this.configuration = configuration;
    }

    @Inject
    public void setObjectFactory(ObjectFactory objectFactory) {
        this.objectFactory = objectFactory;
    }

    @Inject
    public void setUrlRenderer(UrlRenderer urlRenderer) {
    	this.urlRenderer = urlRenderer;
    }

    @Inject
    public void setActionValidatorManager(ActionValidatorManager mgr) {
        this.actionValidatorManager = mgr;
    }


    /*
    * Revised for Portlet actionURL as form action, and add wwAction as hidden
    * field. Refer to template.simple/form.vm
    */
    @Override
    protected void evaluateExtraParams() {
        super.evaluateExtraParams();
        if (validate != null) {
            addParameter("validate", findValue(validate, Boolean.class));
        }

        if (name == null) {
            //make the name the same as the id
            String id = (String) getParameters().get("id");
             if (StringUtils.isNotEmpty(id)) {
                addParameter("name", id);
             }
        }

        if (onsubmit != null) {
            addParameter("onsubmit", findString(onsubmit));
        }

        if (onreset != null) {
            addParameter("onreset", findString(onreset));
        }

        if (target != null) {
            addParameter("target", findString(target));
        }

        if (enctype != null) {
            addParameter("enctype", findString(enctype));
        }

        if (method != null) {
            addParameter("method", findString(method));
        }

        if (acceptcharset != null) {
            addParameter("acceptcharset", findString(acceptcharset));
        }

        // keep a collection of the tag names for anything special the templates might want to do (such as pure client
        // side validation)
        if (!parameters.containsKey("tagNames")) {
            // we have this if check so we don't do this twice (on open and close of the template)
            addParameter("tagNames", new ArrayList());
        }

        if (focusElement != null) {
            addParameter("focusElement", findString(focusElement));
        }
    }

    /**
     * Form component determine the its HTML element id as follows:-
     * <ol>
     *    <li>if an 'id' attribute is specified.</li>
     *    <li>if an 'action' attribute is specified, it will be used as the id.</li>
     * </ol>
     */
    @Override
    protected void populateComponentHtmlId(Form form) {
        if (id != null) {
            super.populateComponentHtmlId(null);
        }

        // if no id given, it will be tried to generate it from the action attribute
        // by the urlRenderer implementation
        urlRenderer.renderFormUrl(this);
    }

    /**
     * Evaluate client side JavaScript Enablement.
     * @param actionName the actioName to check for
     * @param namespace the namespace to check for
     * @param actionMethod the method to ckeck for
     */
    protected void evaluateClientSideJsEnablement(String actionName, String namespace, String actionMethod) {

        // Only evaluate if Client-Side js is to be enable when validate=true
        Boolean validate = (Boolean) getParameters().get("validate");
        if (validate != null && validate) {

            addParameter("performValidation", Boolean.FALSE);

            RuntimeConfiguration runtimeConfiguration = configuration.getRuntimeConfiguration();
            ActionConfig actionConfig = runtimeConfiguration.getActionConfig(namespace, actionName);

            if (actionConfig != null) {
                List<InterceptorMapping> interceptors = actionConfig.getInterceptors();
                for (InterceptorMapping interceptorMapping : interceptors) {
                    if (ValidationInterceptor.class.isInstance(interceptorMapping.getInterceptor())) {
                        ValidationInterceptor validationInterceptor = (ValidationInterceptor) interceptorMapping.getInterceptor();

                        Set excludeMethods = validationInterceptor.getExcludeMethodsSet();
                        Set includeMethods = validationInterceptor.getIncludeMethodsSet();

                        if (MethodFilterInterceptorUtil.applyMethod(excludeMethods, includeMethods, actionMethod)) {
                            addParameter("performValidation", Boolean.TRUE);
                        }
                        return;
                    }
                }
            }
        }
    }

    public List getValidators(String name) {
        Class actionClass = (Class) getParameters().get("actionClass");
        if (actionClass == null) {
            return Collections.EMPTY_LIST;
        }

        String formActionValue = findString(action);
        ActionMapping mapping = actionMapper.getMappingFromActionName(formActionValue);

        if (mapping == null) {
            mapping =  actionMapper.getMappingFromActionName((String) getParameters().get("actionName"));
        }

        if (mapping == null) {
            return Collections.EMPTY_LIST;
        }

        String actionName = mapping.getName();

        String methodName = null;
        if (isValidateAnnotatedMethodOnly(actionName)) {
            methodName = mapping.getMethod();
        }
        
        List<Validator> actionValidators = actionValidatorManager.getValidators(actionClass, actionName, methodName);
        List<Validator> validators = new ArrayList<>();

        findFieldValidators(name, actionClass, actionName, actionValidators, validators, "");

        return validators;
    }

    private boolean isValidateAnnotatedMethodOnly(String actionName) {
        RuntimeConfiguration runtimeConfiguration = configuration.getRuntimeConfiguration();
        String actionNamespace = TagUtils.buildNamespace(actionMapper, stack, request);
        ActionConfig actionConfig = runtimeConfiguration.getActionConfig(actionNamespace, actionName);

        if (actionConfig != null) {
            List<InterceptorMapping> interceptors = actionConfig.getInterceptors();
            for (InterceptorMapping interceptorMapping : interceptors) {
                if (ValidationInterceptor.class.isInstance(interceptorMapping.getInterceptor())) {
                    ValidationInterceptor validationInterceptor = (ValidationInterceptor) interceptorMapping.getInterceptor();
                    return validationInterceptor.isValidateAnnotatedMethodOnly();
                }
            }
        }
        return false;
    }

    private void findFieldValidators(String name, Class actionClass, String actionName,
                                     List<Validator> validatorList, List<Validator> resultValidators, String prefix) {

        for (Validator validator : validatorList) {
            if (validator instanceof FieldValidator) {
                FieldValidator fieldValidator = (FieldValidator) validator;

                if (validator instanceof VisitorFieldValidator) {
                    VisitorFieldValidator vfValidator = (VisitorFieldValidator) fieldValidator;
                    Class clazz = getVisitorReturnType(actionClass, vfValidator.getFieldName());
                    if (clazz == null) {
                        continue;
                    }

                    List<Validator> visitorValidators = actionValidatorManager.getValidators(clazz, actionName);
                    String vPrefix = prefix + (vfValidator.isAppendPrefix() ? vfValidator.getFieldName() + "." : "");
                    findFieldValidators(name, clazz, actionName, visitorValidators, resultValidators, vPrefix);
                } else if ((prefix + fieldValidator.getFieldName()).equals(name)) {
                    if (StringUtils.isNotBlank(prefix)) {
                        //fixing field name for js side
                        FieldVisitorValidatorWrapper wrap = new FieldVisitorValidatorWrapper(fieldValidator, prefix);
                        resultValidators.add(wrap);
                    } else {
                        resultValidators.add(fieldValidator);
                    }
                }
            }
        }
    }

    /**
     * Wrap field validator, add visitor's field prefix to the field name.
     * Javascript side is not aware of the visitor validators
     * and does not know how to prefix the fields.
     */
    /*
     * Class is public because Freemarker has problems accessing properties.
     */
    public static class FieldVisitorValidatorWrapper implements FieldValidator {
        private FieldValidator fieldValidator;
        private String namePrefix;
        public FieldVisitorValidatorWrapper(FieldValidator fv, String namePrefix) {
            this.fieldValidator = fv;
            this.namePrefix = namePrefix;
        }
        public String getValidatorType() {
            return "field-visitor";
        }
        public String getFieldName() {
            return namePrefix + fieldValidator.getFieldName();
        }
        public FieldValidator getFieldValidator() {
            return fieldValidator;
        }
        public void setFieldValidator(FieldValidator fieldValidator) {
            this.fieldValidator = fieldValidator;
        }
        public String getDefaultMessage() {
            return fieldValidator.getDefaultMessage();
        }
        public String getMessage(Object object) {
            return fieldValidator.getMessage(object);
        }
        public String getMessageKey() {
            return fieldValidator.getMessageKey();
        }
        public String[] getMessageParameters() {
            return fieldValidator.getMessageParameters();
        }
        public ValidatorContext getValidatorContext() {
            return fieldValidator.getValidatorContext();
        }
        public void setDefaultMessage(String message) {
            fieldValidator.setDefaultMessage(message);
        }
        public void setFieldName(String fieldName) {
            fieldValidator.setFieldName(fieldName);
        }
        public void setMessageKey(String key) {
            fieldValidator.setMessageKey(key);
        }
        public void setMessageParameters(String[] messageParameters) {
            fieldValidator.setMessageParameters(messageParameters);
        }
        public void setValidatorContext(ValidatorContext validatorContext) {
            fieldValidator.setValidatorContext(validatorContext);
        }
        public void setValidatorType(String type) {
            fieldValidator.setValidatorType(type);
        }
        public void setValueStack(ValueStack stack) {
            fieldValidator.setValueStack(stack);
        }
        public void validate(Object object) throws ValidationException {
            fieldValidator.validate(object);
        }
        public String getNamePrefix() {
            return namePrefix;
        }
        public void setNamePrefix(String namePrefix) {
            this.namePrefix = namePrefix;
        }
    }

    /**
     * Return type of visited object.
     *
     * @param actionClass action class
     * @param visitorFieldName field name
     * @return type of visited object
     */
    @SuppressWarnings("unchecked")
    protected Class getVisitorReturnType(Class actionClass, String visitorFieldName) {
        if (visitorFieldName == null) {
            return null;
        }
        String methodName = "get" + StringUtils.capitalize(visitorFieldName);
        try {
            Method method = actionClass.getMethod(methodName, new Class[0]);
            return method.getReturnType();
        } catch (NoSuchMethodException e) {
            return null;
        }
    }


    /**
     * Get a incrementing sequence unique to this <code>Form</code> component.
     * It is used by <code>Form</code> component's child that might need a
     * sequence to make them unique.
     *
     * @return int
     */
    protected int getSequence() {
        return sequence++;
    }

    @StrutsTagAttribute(description="HTML onsubmit attribute")
    public void setOnsubmit(String onsubmit) {
        this.onsubmit = onsubmit;
    }

    @StrutsTagAttribute(description="HTML onreset attribute")
    public void setOnreset(String onreset) {
        this.onreset = onreset;
    }

    @StrutsTagAttribute(description="Set action name to submit to, without .action suffix", defaultValue="current action")
    public void setAction(String action) {
        this.action = action;
    }

    @StrutsTagAttribute(description="HTML form target attribute")
    public void setTarget(String target) {
        this.target = target;
    }

    @StrutsTagAttribute(description="HTML form enctype attribute")
    public void setEnctype(String enctype) {
        this.enctype = enctype;
    }

    @StrutsTagAttribute(description="HTML form method attribute")
    public void setMethod(String method) {
        this.method = method;
    }

    @StrutsTagAttribute(description="Namespace for action to submit to", defaultValue="current namespace")
    public void setNamespace(String namespace) {
        this.namespace = namespace;
    }

    @StrutsTagAttribute(description="Whether client side/remote validation should be performed. Only" +
                " useful with theme xhtml/ajax", type="Boolean", defaultValue="false")
    public void setValidate(String validate) {
        this.validate = validate;
    }

    @StrutsTagAttribute(description="The portlet mode to display after the form submit")
    public void setPortletMode(String portletMode) {
        this.portletMode = portletMode;
    }

    @StrutsTagAttribute(description="The window state to display after the form submit")
    public void setWindowState(String windowState) {
        this.windowState = windowState;
    }

    @StrutsTagAttribute(description="The accepted charsets for this form. The values may be comma or blank delimited.")
    public void setAcceptcharset(String acceptcharset) {
        this.acceptcharset = acceptcharset;
    }

    @StrutsTagAttribute(description="Id of element that will receive the focus when page loads.")
    public void setFocusElement(String focusElement) {
        this.focusElement = focusElement;
    }

    @StrutsTagAttribute(description="Whether actual context should be included in URL", type="Boolean", defaultValue="true")
    public void setIncludeContext(boolean includeContext) {
        this.includeContext = includeContext;
    }
}
