/*
 * 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.component.validate;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.el.ELContext;
import javax.el.ValueExpression;
import javax.el.ValueReference;
import javax.faces.FacesException;
import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.component.visit.VisitCallback;
import javax.faces.component.visit.VisitContext;
import javax.faces.component.visit.VisitResult;
import javax.faces.context.FacesContext;
import static javax.faces.validator.BeanValidator.EMPTY_VALIDATION_GROUPS_PATTERN;
import static javax.faces.validator.BeanValidator.MESSAGE_ID;
import static javax.faces.validator.BeanValidator.VALIDATION_GROUPS_DELIMITER;
import static javax.faces.validator.BeanValidator.VALIDATOR_FACTORY_KEY;
import javax.faces.validator.Validator;
import javax.faces.validator.ValidatorException;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.ValidatorFactory;
import javax.validation.groups.Default;
import javax.validation.metadata.BeanDescriptor;
import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFProperty;
import org.apache.myfaces.core.api.shared.ELContextDecorator;
import org.apache.myfaces.core.api.shared.FacesMessageInterpolator;
import org.apache.myfaces.core.api.shared.ValueReferenceResolver;
import org.apache.myfaces.util.lang.Assert;
import org.apache.myfaces.util.lang.ClassUtils;
import org.apache.myfaces.util.MessageUtils;
import org.apache.myfaces.util.MyFacesObjectInputStream;
import org.apache.myfaces.util.ExternalSpecifications;
import org.apache.myfaces.util.lang.FastByteArrayOutputStream;

public class WholeBeanValidator implements Validator
{
    private static final Logger log = Logger.getLogger(WholeBeanValidator.class.getName());
    
    private static final Class<?>[] DEFAULT_VALIDATION_GROUPS_ARRAY = new Class<?>[] { Default.class };
    
    private static final String CANDIDATE_COMPONENT_VALUES_MAP = "oam.WBV.candidatesMap";
    
    private static final String BEAN_VALIDATION_FAILED = "oam.WBV.validationFailed";

    private Class<?>[] validationGroupsArray;

    @Override
    public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException
    {
        Assert.notNull(context, "context");
        Assert.notNull(component, "component");

        ValueExpression valueExpression = component.getValueExpression("value");
        if (valueExpression == null)
        {
            log.warning("cannot validate component with empty value: " 
                    + component.getClientId(context));
            return;
        }

        Object base = valueExpression.getValue(context.getELContext());
                
        Class<?> valueBaseClass = base.getClass();
        if (valueBaseClass == null)
        {
            return;
        }

        // Initialize Bean Validation.
        ValidatorFactory validatorFactory = createValidatorFactory(context);
        javax.validation.Validator validator = createValidator(validatorFactory, context, 
                (ValidateWholeBeanComponent)component);
        BeanDescriptor beanDescriptor = validator.getConstraintsForClass(valueBaseClass);
        if (!beanDescriptor.isBeanConstrained())
        {
            return;
        }
        
        // Note that validationGroupsArray was initialized when createValidator was called
        Class[] validationGroupsArray = this.validationGroupsArray;

        // Delegate to Bean Validation.
        
        // TODO: Use validator.validate(...) over the copy instance.
        
        Boolean beanValidationFailed = (Boolean) context.getViewRoot().getTransientStateHelper()
                .getTransient(BEAN_VALIDATION_FAILED);
        
        if (Boolean.TRUE.equals(beanValidationFailed))
        {
            // JSF 2.3 Skip class level validation
            return;
        }
        
        Map<String, Object> candidatesMap = (Map<String, Object>) context.getViewRoot()
                .getTransientStateHelper().getTransient(CANDIDATE_COMPONENT_VALUES_MAP);
        if (candidatesMap != null)
        {
            Object copy = createBeanCopy(base);
            
            UpdateBeanCopyCallback callback = new UpdateBeanCopyCallback(this, base, copy, candidatesMap);
            context.getViewRoot().visitTree(
                    VisitContext.createVisitContext(context, candidatesMap.keySet(), null), 
                    callback);
            
            Set<ConstraintViolation<Object>> constraintViolations = validator.validate(copy, validationGroupsArray);
            if (!constraintViolations.isEmpty())
            {
                Set<FacesMessage> messages = new LinkedHashSet<>(constraintViolations.size());
                for (ConstraintViolation constraintViolation : constraintViolations)
                {
                    String message = constraintViolation.getMessage();
                    Object[] args = new Object[]{ message, MessageUtils.getLabel(context, component) };
                    FacesMessage msg = MessageUtils.getMessage(FacesMessage.SEVERITY_ERROR, MESSAGE_ID, args, context);
                    messages.add(msg);
                }
                throw new ValidatorException(messages);
            }
        }
    }
    
    private Object createBeanCopy(Object base)
    {
        Object copy = null;
        try
        {
            copy = base.getClass().newInstance();
        }
        catch (Exception ex)
        {
            log.log(Level.FINEST, null, ex);
        }
        
        if (base instanceof Serializable)
        {
            copy = copySerializableObject(base);
        }
        else if(base instanceof Cloneable)
        { 
            Method cloneMethod;
            try
            {
                cloneMethod = base.getClass().getMethod("clone");
                copy = cloneMethod.invoke(base);
            }
            catch (Exception ex) 
            {
                log.log(Level.FINEST, null, ex);
            }
        }
        else
        {
            Class<?> clazz = base.getClass();
            try
            {
                Constructor<?> copyConstructor = clazz.getConstructor(clazz);
                if (copyConstructor != null)
                {
                    copy = copyConstructor.newInstance(base);
                }
            }
            catch (Exception ex)
            {
                log.log(Level.FINEST, null, ex);
            }
        }
        
        if (copy == null)
        {
            throw new FacesException("Cannot create copy for wholeBeanValidator: "+base.getClass().getName());
        }
        
        return copy;
    }
    
    private Object copySerializableObject(Object base)
    {
        try 
        {
            FastByteArrayOutputStream baos = new FastByteArrayOutputStream(256);
            try (ObjectOutputStream oos = new ObjectOutputStream(baos))
            {
                oos.writeObject(base);
                oos.flush();
            }

            ObjectInputStream ois = new MyFacesObjectInputStream(baos.getInputStream());
            try 
            {
                return ois.readObject();
            }
            catch (ClassNotFoundException e)
            {
                //e.printStackTrace();
            }
        }
        catch (IOException e) 
        {
            //e.printStackTrace();
        }

        return null;
    }    
    
    private javax.validation.Validator createValidator(final ValidatorFactory validatorFactory, 
            FacesContext context, ValidateWholeBeanComponent component)
    {
        // Set default validation group when setValidationGroups has not been called.
        // The null check is there to prevent it from happening twice.
        if (validationGroupsArray == null)
        {
            postSetValidationGroups(component);
        }

        return validatorFactory //
                .usingContext() //
                .messageInterpolator(new FacesMessageInterpolator(
                        validatorFactory.getMessageInterpolator(), context)) //
                .getValidator();

    }


    /**
     * Get the ValueReference from the ValueExpression.
     *
     * @param valueExpression The ValueExpression for value.
     * @param context The FacesContext.
     * @return A ValueReferenceWrapper with the necessary information about the ValueReference.
     */
    private ValueReference getValueReference(
            final ValueExpression valueExpression, final FacesContext context)
    {
        ELContext elCtx = context.getELContext();

        return ValueReferenceResolver.resolve(valueExpression, elCtx);
    }

    /**
     * This method creates ValidatorFactory instances or retrieves them from the container.
     *
     * Once created, ValidatorFactory instances are stored in the container under the key
     * VALIDATOR_FACTORY_KEY for performance.
     *
     * @param context The FacesContext.
     * @return The ValidatorFactory instance.
     * @throws FacesException if no ValidatorFactory can be obtained because: a) the
     * container is not a Servlet container or b) because Bean Validation is not available.
     */
    private ValidatorFactory createValidatorFactory(FacesContext context)
    {
        Map<String, Object> applicationMap = context.getExternalContext().getApplicationMap();
        Object attr = applicationMap.get(VALIDATOR_FACTORY_KEY);
        if (attr instanceof ValidatorFactory)
        {
            return (ValidatorFactory) attr;
        }
        else
        {
            synchronized (this)
            {
                if (ExternalSpecifications.isBeanValidationAvailable())
                {
                    ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
                    applicationMap.put(VALIDATOR_FACTORY_KEY, factory);
                    return factory;
                }
                else
                {
                    throw new FacesException("Bean Validation is not present");
                }
            }
        }
    }

    /**
     * Fully initialize the validation groups if needed.
     * If no validation groups are specified, the Default validation group is used.
     */
    private void postSetValidationGroups(ValidateWholeBeanComponent component)
    {
        String validationGroups = getValidationGroups(component);
        if (validationGroups == null || validationGroups.matches(EMPTY_VALIDATION_GROUPS_PATTERN))
        {
            this.validationGroupsArray = DEFAULT_VALIDATION_GROUPS_ARRAY;
        }
        else
        {
            String[] classes = validationGroups.split(VALIDATION_GROUPS_DELIMITER);
            List<Class<?>> validationGroupsList = new ArrayList<Class<?>>(classes.length);

            for (String clazz : classes)
            {
                clazz = clazz.trim();
                if (!clazz.isEmpty())
                {
                    try
                    {
                        Class<?> theClass = ClassUtils.classForName(clazz);

                        // the class was found
                        validationGroupsList.add(theClass);
                    }
                    catch (ClassNotFoundException e)
                    {
                        throw new RuntimeException("Could not load validation group", e);                     
                    }
                }
            }
                    
            this.validationGroupsArray = validationGroupsList.toArray(new Class[validationGroupsList.size()]);
        }
    }

    /**
     * Get the Bean Validation validation groups.
     * @return The validation groups String.
     */
    @JSFProperty
    public String getValidationGroups(ValidateWholeBeanComponent component)
    {
        return component.getValidationGroups();
    }

    /**
     * Set the Bean Validation validation groups.
     * @param validationGroups The validation groups String, separated by
     *                         {@link javax.faces.validator.BeanValidator#VALIDATION_GROUPS_DELIMITER}.
     */
    public void setValidationGroups(ValidateWholeBeanComponent component, final String validationGroups)
    {
        component.setValidationGroups(validationGroups);
    }

    private static class UpdateBeanCopyCallback implements VisitCallback
    {
        private WholeBeanValidator validator;
        private Object wholeBeanBase;
        private Object wholeBeanBaseCopy;
        private Map<String, Object> candidateValuesMap;

        public UpdateBeanCopyCallback(WholeBeanValidator validator, Object wholeBeanBase, Object wholeBeanBaseCopy,
                Map<String, Object> candidateValuesMap)
        {
            this.validator = validator;
            this.wholeBeanBase = wholeBeanBase;
            this.wholeBeanBaseCopy = wholeBeanBaseCopy;
            this.candidateValuesMap = candidateValuesMap;
        }

        @Override
        public VisitResult visit(VisitContext context, UIComponent target)
        {
            // The idea is follow almost the same algorithm used by Bean Validation. This 
            // algorithm calculates the base of the ValueExpression used by the component.
            // Then a simple equals() check will do the trick to decide when to call
            // setValue and affect the model. If the base is the same than the value returned by
            // f:validateWholeBean, you are affecting to same instance.
            
            ValueExpression valueExpression = target.getValueExpression("value");
            if (valueExpression == null)
            {
                log.warning("cannot validate component with empty value: " 
                        + target.getClientId(context.getFacesContext()));
                return VisitResult.ACCEPT;
            }

            // Obtain a reference to the to-be-validated object and the property name.
            ValueReference reference = validator.getValueReference(
                    valueExpression, context.getFacesContext());
            if (reference == null)
            {
                return VisitResult.ACCEPT;
            }
            
            Object base = reference.getBase();
            if (base == null)
            {
                return VisitResult.ACCEPT;
            }

            Object referenceProperty = reference.getProperty();
            if (!(referenceProperty instanceof String))
            {
                // if the property is not a String, the ValueReference does not
                // point to a bean method, but e.g. to a value in a Map, thus we 
                // can exit bean validation here
                return VisitResult.ACCEPT;
            }
                        
            // If the base of the EL expression is the same to the base of the one in f:validateWholeBean
            if (base == this.wholeBeanBase || base.equals(this.wholeBeanBase))
            {
                // Do the trick over ELResolver and apply it to the copy.
                ELContext elCtxDecorator = new ELContextDecorator(context.getFacesContext().getELContext(),
                        new CopyBeanInterceptorELResolver(context.getFacesContext().getApplication().getELResolver(),
                            this.wholeBeanBase, this.wholeBeanBaseCopy));
                
                valueExpression.setValue(elCtxDecorator, candidateValuesMap.get(
                        target.getClientId(context.getFacesContext())));
            }
            
            return VisitResult.ACCEPT;
        }
    }
}