/*
 * 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.logging.log4j.plugins.validation;

import org.apache.logging.log4j.util.ReflectionUtil;

import java.lang.annotation.Annotation;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collection;

/**
 * Utility class to locate an appropriate {@link ConstraintValidator} implementation for an annotation.
 *
 * @since 2.1
 */
public final class ConstraintValidators {

    private ConstraintValidators() {
    }

    /**
     * Finds all relevant {@link ConstraintValidator} objects from an array of annotations. All validators will be
     * {@link ConstraintValidator#initialize(Annotation) initialized} before being returned.
     *
     * @param annotations the annotations to find constraint validators for
     * @return a collection of ConstraintValidators for the given annotations
     */
    public static Collection<ConstraintValidator<?>> findValidators(final Annotation... annotations) {
        final Collection<ConstraintValidator<?>> validators =
            new ArrayList<>();
        for (final Annotation annotation : annotations) {
            final Class<? extends Annotation> type = annotation.annotationType();
            if (type.isAnnotationPresent(Constraint.class)) {
                final ConstraintValidator<?> validator = getValidator(annotation, type);
                if (validator != null) {
                    validators.add(validator);
                }
            }
        }
        return validators;
    }

    private static <A extends Annotation> ConstraintValidator<A> getValidator(final A annotation,
                                                                              final Class<? extends A> type) {
        final Constraint constraint = type.getAnnotation(Constraint.class);
        final Class<? extends ConstraintValidator<?>> validatorClass = constraint.value();
        if (type.equals(getConstraintValidatorAnnotationType(validatorClass))) {
            @SuppressWarnings("unchecked") // I don't think we could be any more thorough in validation here
            final ConstraintValidator<A> validator = (ConstraintValidator<A>)
                ReflectionUtil.instantiate(validatorClass);
            validator.initialize(annotation);
            return validator;
        }
        return null;
    }

    private static Type getConstraintValidatorAnnotationType(final Class<? extends ConstraintValidator<?>> type) {
        for (final Type parentType : type.getGenericInterfaces()) {
            if (parentType instanceof ParameterizedType) {
                final ParameterizedType parameterizedType = (ParameterizedType) parentType;
                if (ConstraintValidator.class.equals(parameterizedType.getRawType())) {
                    return parameterizedType.getActualTypeArguments()[0];
                }
            }
        }
        return Void.TYPE;
    }
}
