/*
 * 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.myfaces.extensions.validator.core.initializer.component;

import org.apache.myfaces.extensions.validator.core.ExtValContext;
import org.apache.myfaces.extensions.validator.core.ExtValCoreConfiguration;
import org.apache.myfaces.extensions.validator.internal.UsageInformation;
import org.apache.myfaces.extensions.validator.internal.UsageCategory;
import org.apache.myfaces.extensions.validator.internal.ToDo;
import org.apache.myfaces.extensions.validator.internal.Priority;
import org.apache.myfaces.extensions.validator.util.ExtValUtils;
import org.apache.myfaces.extensions.validator.util.ReflectionUtils;
import org.apache.myfaces.extensions.validator.core.metadata.CommonMetaDataKeys;

import javax.faces.context.FacesContext;
import javax.faces.component.UIComponent;
import javax.faces.component.html.HtmlInputText;
import javax.faces.component.html.HtmlInputSecret;
import javax.faces.component.html.HtmlSelectBooleanCheckbox;
import javax.faces.component.html.HtmlSelectOneListbox;
import javax.faces.component.html.HtmlSelectOneMenu;
import javax.faces.component.html.HtmlSelectOneRadio;
import javax.faces.component.html.HtmlSelectManyCheckbox;
import javax.faces.component.html.HtmlSelectManyListbox;
import javax.faces.component.html.HtmlSelectManyMenu;
import javax.faces.component.html.HtmlInputTextarea;
import java.util.Map;

/**
 * Basic implementation of a {@link ComponentInitializer} which allows an easier handling of required validations and
 * provides a default implementation for standard components.
 *
 * @author Gerhard Petracek
 * @since x.x.3
 */
@UsageInformation(UsageCategory.REUSE)
public abstract class AbstractHtmlCoreComponentsComponentInitializer implements ComponentInitializer
{
    //short because it influences the state
    protected static final String INITIAL_MARKUP_META_DATA_KEY = "OAM_EV_MARKUP_METADATA";

    protected Boolean forceComponentInitialization;

    /**
     * If the component is one of the standard input components, the max length attribute is configured and the
     * required attribute is configured (if empty field validation and required initialization is activated)
     *
     * @param facesContext The JSF Context
     * @param uiComponent The component which should be initialised
     * @param metaData map which contains the transformed meta-data
     */
    public void configureComponent(FacesContext facesContext, UIComponent uiComponent, Map<String, Object> metaData)
    {
        if(processComponent(uiComponent))
        {
            if(validateEmptyFields() && isRequiredInitializationActive())
            {
                configureRequiredAttribute(facesContext, uiComponent, metaData);
            }

            configureMaxLengthAttribute(facesContext, uiComponent, metaData);
        }
    }

    /**
     * Uses the config introduced by JSF 2 for specifying if
     * fields without content should be available for required validation.
     *
     * @return true if fields with empty values should be validated, false otherwise.
     */
    protected boolean validateEmptyFields()
    {
        return ExtValUtils.validateEmptyFields();
    }

    /**
     * Uses the config introduced by prev. ExtVal versions for specifying if
     * required initialization should be used
     * (it's useful e.g. for client-side validations provided by libs like trinidad).
     *
     * @return true if ExtVal should transfer meta-data for required fields to the component
     */
    protected boolean isRequiredInitializationActive()
    {
        return ExtValUtils.isRequiredInitializationActive();
    }

    /**
     * The concrete implementation has to initialize the component based on the given meta-data map.
     * This method is only called if all pre-conditions are fulfilled.
     *
     * @param facesContext The JSF Context
     * @param uiComponent The UIComponent which should be configured.
     * @param metaData map which contains the transformed meta-data
     */
    protected abstract void configureRequiredAttribute(FacesContext facesContext,
                                                       UIComponent uiComponent,
                                                       Map<String, Object> metaData);

    /**
     * Activates the implementation for special components (-> other components will be ignored).
     *
     * @param uiComponent The UIComponent which should be configured.
     * @return Should the component be initialized.
     */
    protected boolean processComponent(UIComponent uiComponent)
    {
        return uiComponent instanceof HtmlInputText ||
               uiComponent instanceof HtmlInputSecret ||
               uiComponent instanceof HtmlSelectBooleanCheckbox ||
               uiComponent instanceof HtmlSelectOneListbox ||
               uiComponent instanceof HtmlSelectOneMenu ||
               uiComponent instanceof HtmlSelectOneRadio ||
               uiComponent instanceof HtmlSelectManyCheckbox ||
               uiComponent instanceof HtmlSelectManyListbox ||
               uiComponent instanceof HtmlSelectManyMenu ||
               uiComponent instanceof HtmlInputTextarea;
    }

    /**
     * if there is no special attribute at the component which should overrule
     * the annotated property return true!
     *
     * @param uiComponent component which implements the EditableValueHolder interface
     * @return false to overrule the annotated property e.g. if component is readonly
     */
    @ToDo(value = Priority.MEDIUM, description = "refactor")
    protected boolean isRequiredInitializationSupported(UIComponent uiComponent)
    {
        boolean isReadOnly = !Boolean.FALSE.equals(ReflectionUtils.tryToInvokeMethod(
                uiComponent, ReflectionUtils.tryToGetMethod(uiComponent.getClass(), "isReadonly")));
        boolean isDisabled = !Boolean.FALSE.equals(ReflectionUtils.tryToInvokeMethod(
                uiComponent, ReflectionUtils.tryToGetMethod(uiComponent.getClass(), "isDisabled")));

        return !(isReadOnly || isDisabled);
    }

    /**
     * This default implementation uses the transformed meta-data stored via the ({@link CommonMetaDataKeys#MAX_LENGTH}
     * key for initializing e.g. the maxLength attribute of the current component
     * (of type {@link HtmlInputText} or {@link HtmlInputSecret}.
     *
     * @param facesContext The JSF Context
     * @param uiComponent  The component to configure.
     * @param metaData map which contains the transformed meta-data
     */
    protected void configureMaxLengthAttribute(FacesContext facesContext,
                                               UIComponent uiComponent,
                                               Map<String, Object> metaData)
    {
        if(metaData.containsKey(CommonMetaDataKeys.MAX_LENGTH))
        {
            Object maxLength = metaData.get(CommonMetaDataKeys.MAX_LENGTH);

            if(!(maxLength instanceof Integer))
            {
                return;
            }

            init(); //lazy init

            if(uiComponent instanceof HtmlInputText)
            {
                HtmlInputText htmlInputText = (HtmlInputText)uiComponent;

                if (this.forceComponentInitialization)
                {
                    htmlInputText.setMaxlength((Integer) maxLength);
                }
                else
                {
                    Integer initialMaxLength = (Integer)
                        htmlInputText.getAttributes().get(INITIAL_MARKUP_META_DATA_KEY);

                    if (initialMaxLength == null)
                    {
                        initialMaxLength = htmlInputText.getMaxlength(); //value overriden by the component
                        htmlInputText.getAttributes().put(INITIAL_MARKUP_META_DATA_KEY, initialMaxLength);
                    }

                    // only override maxlength if not already set by xhtml definition
                    if (initialMaxLength <= 0)
                    {
                        htmlInputText.setMaxlength((Integer) maxLength);
                    }
                }
            }
            else if(uiComponent instanceof HtmlInputSecret)
            {
                HtmlInputSecret htmlInputSecret = (HtmlInputSecret)uiComponent;

                if (this.forceComponentInitialization)
                {
                    htmlInputSecret.setMaxlength((Integer)maxLength);
                }
                else
                {
                    Integer initialMaxLength = (Integer)
                        htmlInputSecret.getAttributes().get(INITIAL_MARKUP_META_DATA_KEY);

                    if (initialMaxLength == null)
                    {
                        initialMaxLength = htmlInputSecret.getMaxlength(); //value overriden by the component
                        htmlInputSecret.getAttributes().put(INITIAL_MARKUP_META_DATA_KEY, initialMaxLength);
                    }

                    // only override maxlength if not already set by xhtml definition
                    if (initialMaxLength <= 0)
                    {
                        htmlInputSecret.setMaxlength((Integer) maxLength);
                    }
                }
            }
        }
    }

    protected void init()
    {
        if (this.forceComponentInitialization == null)
        {
            this.forceComponentInitialization = !ExtValContext.getContext()
                .getModuleConfiguration(ExtValCoreConfiguration.class).activateMarkupMetaData();
        }
    }
}
