/*
 *  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.bval.jsr303.extensions;

import org.apache.bval.Validate;
import org.apache.bval.jsr303.ApacheFactoryContext;
import org.apache.bval.jsr303.AppendValidation;
import org.apache.bval.jsr303.ConstraintAnnotationAttributes;
import org.apache.bval.jsr303.Jsr303MetaBeanFactory;
import org.apache.bval.model.Validation;
import org.apache.bval.util.AccessStrategy;
import org.apache.commons.lang3.ClassUtils;

import javax.validation.Constraint;
import javax.validation.Valid;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;

/**
 * Description: extension to validate parameters/return values of
 * methods/constructors.<br/>
 */
// TODO RSt - move. this is an optional module: move the whole package. core
// code has no dependencies on it
public class MethodValidatorMetaBeanFactory extends Jsr303MetaBeanFactory {
    /**
     * Create a new MethodValidatorMetaBeanFactory instance.
     * 
     * @param factoryContext
     */
    public MethodValidatorMetaBeanFactory(ApacheFactoryContext factoryContext) {
        super(factoryContext);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected boolean hasValidationConstraintsDefined(Method method) {
        return false;
    }

    /**
     * Finish building the specified {@link MethodBeanDescriptorImpl}.
     * 
     * @param descriptor
     */
    public void buildMethodDescriptor(MethodBeanDescriptorImpl descriptor) {
        try {
            buildMethodConstraints(descriptor);
            buildConstructorConstraints(descriptor);
        } catch (Exception e) {
            throw new IllegalArgumentException(e.getMessage(), e);
        }
    }

    private void buildConstructorConstraints(MethodBeanDescriptorImpl beanDesc) throws InvocationTargetException,
        IllegalAccessException {
        beanDesc.setConstructorConstraints(new HashMap<Constructor<?>, ConstructorDescriptor>());

        for (Constructor<?> cons : beanDesc.getMetaBean().getBeanClass().getDeclaredConstructors()) {
            if (!factoryContext.getFactory().getAnnotationIgnores().isIgnoreAnnotations(cons)) {

                ConstructorDescriptorImpl consDesc =
                    new ConstructorDescriptorImpl(beanDesc.getMetaBean(), new Validation[0]);
                beanDesc.putConstructorDescriptor(cons, consDesc);

                Annotation[][] paramsAnnos = cons.getParameterAnnotations();
                int idx = 0;
                for (Annotation[] paramAnnos : paramsAnnos) {
                    ParameterAccess access = new ParameterAccess(cons.getParameterTypes()[idx], idx);
                    processAnnotations(consDesc, paramAnnos, access, idx);
                    idx++;
                }
            }
        }
    }

    private void buildMethodConstraints(MethodBeanDescriptorImpl beanDesc) throws InvocationTargetException,
        IllegalAccessException {
        beanDesc.setMethodConstraints(new HashMap<Method, MethodDescriptor>());

        for (Method method : beanDesc.getMetaBean().getBeanClass().getDeclaredMethods()) {
            if (!factoryContext.getFactory().getAnnotationIgnores().isIgnoreAnnotations(method)) {

                MethodDescriptorImpl methodDesc = new MethodDescriptorImpl(beanDesc.getMetaBean(), new Validation[0]);
                beanDesc.putMethodDescriptor(method, methodDesc);

                // return value validations
                AppendValidationToList validations = new AppendValidationToList();
                ReturnAccess returnAccess = new ReturnAccess(method.getReturnType());
                for (Annotation anno : method.getAnnotations()) {
                    if (anno instanceof Valid || anno instanceof Validate) {
                        methodDesc.setCascaded(true);
                    } else {
                        processAnnotation(anno, methodDesc, returnAccess, validations);
                    }
                }
                methodDesc.addValidations(validations.getValidations());

                // parameter validations
                Annotation[][] paramsAnnos = method.getParameterAnnotations();
                int idx = 0;
                for (Annotation[] paramAnnos : paramsAnnos) {
                    ParameterAccess access = new ParameterAccess(method.getParameterTypes()[idx], idx);
                    processAnnotations(methodDesc, paramAnnos, access, idx);
                    idx++;
                }
            }
        }
    }

    private void processAnnotations(ProcedureDescriptor methodDesc, Annotation[] paramAnnos, AccessStrategy access,
        int idx) throws InvocationTargetException, IllegalAccessException {
        AppendValidationToList validations = new AppendValidationToList();
        boolean cascaded = false;
        for (Annotation anno : paramAnnos) {
            if (anno instanceof Valid || anno instanceof Validate) {
                cascaded = true;
            } else {
                processAnnotation(anno, methodDesc, access, validations);
            }
        }
        ParameterDescriptorImpl paramDesc =
            new ParameterDescriptorImpl(methodDesc.getMetaBean(), validations.getValidations().toArray(
                new Validation[validations.getValidations().size()]));
        paramDesc.setIndex(idx);
        paramDesc.setCascaded(cascaded);
        methodDesc.getParameterDescriptors().add(paramDesc);
    }

    private <A extends Annotation> void processAnnotation(A annotation, ProcedureDescriptor desc,
        AccessStrategy access, AppendValidation validations) throws InvocationTargetException, IllegalAccessException {

        if (annotation instanceof Valid || annotation instanceof Validate) {
            desc.setCascaded(true);
        } else {
            Constraint vcAnno = annotation.annotationType().getAnnotation(Constraint.class);
            if (vcAnno != null) {
                annotationProcessor.processAnnotation(annotation, null,
                    ClassUtils.primitiveToWrapper((Class<?>) access.getJavaType()), access, validations);
            } else {
                /**
                 * Multi-valued constraints
                 */
                if (ConstraintAnnotationAttributes.VALUE.isDeclaredOn(annotation.annotationType())) {
                    Annotation[] children = ConstraintAnnotationAttributes.VALUE.getValue(annotation);
                    if (children != null) {
                        for (Annotation child : children) {
                            processAnnotation(child, desc, access, validations); // recursion
                        }
                    }
                }
            }
        }
    }

}
