/*
 * 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.interceptor;

import org.apache.myfaces.extensions.validator.internal.UsageCategory;
import org.apache.myfaces.extensions.validator.internal.UsageInformation;
import org.apache.myfaces.extensions.validator.core.validation.strategy.ValidationStrategy;
import org.apache.myfaces.extensions.validator.core.validation.SkipValidationEvaluator;
import org.apache.myfaces.extensions.validator.core.validation.NullValueAwareValidationStrategy;
import org.apache.myfaces.extensions.validator.core.validation.EmptyValueAwareValidationStrategy;
import org.apache.myfaces.extensions.validator.core.metadata.extractor.MetaDataExtractor;
import org.apache.myfaces.extensions.validator.core.metadata.MetaDataEntry;
import org.apache.myfaces.extensions.validator.core.property.PropertyInformation;
import org.apache.myfaces.extensions.validator.core.ExtValContext;
import org.apache.myfaces.extensions.validator.util.ExtValUtils;
import org.apache.myfaces.extensions.validator.util.ProxyUtils;

import javax.faces.context.FacesContext;
import javax.faces.component.UIComponent;
import java.util.Map;
import java.lang.annotation.Annotation;

/**
 * @since 1.x.1
 */
@UsageInformation(UsageCategory.INTERNAL)
public class ValidationInterceptor extends AbstractValidationInterceptor
{
    @Override
    protected boolean isRequiredInitializationSupported()
    {
        return true;
    }

    protected void initComponent(FacesContext facesContext, UIComponent uiComponent)
    {
        logger.finest("start to init component " + uiComponent.getClass().getName());

        Map<String, Object> metaDataResult = getTransformedMetaDataFor(facesContext, uiComponent);

        //get component initializer for the current component and configure it
        //also in case of skipped validation to reset e.g. the required attribute
        if(!metaDataResult.isEmpty())
        {
            ExtValUtils.configureComponentWithMetaData(facesContext, uiComponent, metaDataResult);
        }

        logger.finest("init component of " + uiComponent.getClass().getName() + " finished");
    }

    protected Map<String, Object> getTransformedMetaDataFor(FacesContext facesContext, UIComponent uiComponent)
    {
        return ExtValUtils.getTransformedMetaDataFor(facesContext, uiComponent, getModuleKey());
    }

    protected void processValidation(FacesContext facesContext, UIComponent uiComponent, Object convertedObject)
    {
        MetaDataExtractor metaDataExtractor = ExtValUtils
                .getComponentMetaDataExtractorWith(getPropertiesForComponentMetaDataExtractor(uiComponent));

        PropertyInformation propertyInformation = metaDataExtractor.extract(facesContext, uiComponent);

        try
        {
            logger.finest("start validation");

            processFieldValidation(facesContext, uiComponent, convertedObject, propertyInformation);
        }
        finally
        {
            logger.finest("validation finished");
        }
    }

    protected MetaDataExtractor getComponentMetaDataExtractor(Map<String, Object> properties)
    {
        return ExtValUtils.getComponentMetaDataExtractorWith(properties);
    }

    protected void processFieldValidation(FacesContext facesContext,
                                          UIComponent uiComponent,
                                          Object convertedObject,
                                          PropertyInformation propertyInformation)
    {
        ValidationStrategy validationStrategy;
        SkipValidationEvaluator skipValidationEvaluator = ExtValContext.getContext().getSkipValidationEvaluator();
        for (MetaDataEntry entry : propertyInformation.getMetaDataEntries())
        {
            validationStrategy = ExtValUtils.getValidationStrategyForMetaData(entry.getKey());

            if (validationStrategy != null &&
                    isValidationStrategyCompatibleWithValue(validationStrategy, convertedObject, entry))
            {
                if(skipValidationEvaluator.skipValidation(facesContext, uiComponent, validationStrategy, entry))
                {
                    logger.finest("skip validation of " + entry.getValue() +
                            " with " + validationStrategy.getClass().getName());
                    //don't break maybe there are constraints which don't support the skip-mechanism
                    continue;
                }

                logger.finest("validate " + entry.getValue() + " with " + validationStrategy.getClass().getName());

                try
                {
                    if(entry.getValue() instanceof Annotation)
                    {
                        if(!ExtValUtils.executeLocalBeforeValidationInterceptors(
                                facesContext, uiComponent, convertedObject,
                                PropertyInformation.class.getName(), propertyInformation,
                                entry.getValue(Annotation.class)))
                        {
                            continue;
                        }
                    }

                    /*
                     * validation
                     */
                    validationStrategy.validate(facesContext, uiComponent, entry, convertedObject);
                }
                finally
                {
                    if(entry.getValue() instanceof Annotation)
                    {
                        ExtValUtils.executeLocalAfterValidationInterceptors(
                                facesContext, uiComponent, convertedObject,
                                PropertyInformation.class.getName(), propertyInformation,
                                entry.getValue(Annotation.class));
                    }
                }
            }
            else if(validationStrategy == null)
            {
                logger.finest("no validation strategy found for " + entry.getValue());
            }
        }
    }

    protected boolean isValidationStrategyCompatibleWithValue(
            ValidationStrategy validationStrategy, Object value, MetaDataEntry entry /*for add-ons*/)
    {
        if(value == null)
        {
            Class validationStrategyClass = ProxyUtils.getUnproxiedClass(validationStrategy.getClass());
            return validationStrategyClass.isAnnotationPresent(NullValueAwareValidationStrategy.class);
        }

        return !"".equals(value) || ProxyUtils.getUnproxiedClass(validationStrategy.getClass())
                .isAnnotationPresent(EmptyValueAwareValidationStrategy.class);
    }

    @Override
    /**
     * to ensure backward compatibility
     */
    protected boolean interpretEmptyStringValuesAsNull()
    {
        return false;
    }

    @Override
    protected boolean recordProcessedInformation()
    {
        return true;
    }
}
