/*
 * 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.deltaspike.beanvalidation.impl;

import java.lang.reflect.Method;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorFactory;
import javax.validation.Validation;

import org.apache.deltaspike.core.api.provider.BeanProvider;
import org.apache.deltaspike.core.util.ReflectionUtils;

/**
 * A factory for creating CDI Aware/Enabled ConstraintValidators.
 *
 */
public class CDIAwareConstraintValidatorFactory implements
        ConstraintValidatorFactory
{
    private static final String RELEASE_INSTANCE_METHOD_NAME = "releaseInstance";
    private static volatile Boolean releaseInstanceMethodFound;
    private static Method releaseInstanceMethod;

    private final Logger log = Logger.getLogger(CDIAwareConstraintValidatorFactory.class.getName());

    private final ConstraintValidatorFactory delegate;

    public CDIAwareConstraintValidatorFactory()
    {
        delegate = Validation.byDefaultProvider().configure().getDefaultConstraintValidatorFactory();
        if (log.isLoggable(Level.CONFIG))
        {
            log.config("Setting up delegate ConstraintValidatorFactory as " +
                    delegate.getClass().getCanonicalName());
        }
    }

    @Override
    public <T extends ConstraintValidator<?, ?>> T getInstance(Class<T> validatorClass)
    {
        T resolvedInst = BeanProvider.getContextualReference(validatorClass, true);
        if (resolvedInst == null)
        {
            if (log.isLoggable(Level.CONFIG))
            {
                log.config("No contextual instances found for class " + validatorClass.getCanonicalName() +
                         " delegating to DefaultProvider behavior.");
            }
            resolvedInst = this.delegate.getInstance(validatorClass);
        }
        return resolvedInst;
    }

    //BV v1.1+
    public void releaseInstance(ConstraintValidator<?, ?> constraintValidator)
    {
        if (releaseInstanceMethodFound == null)
        {
            lazyInit();
        }
        if (Boolean.TRUE.equals(releaseInstanceMethodFound))
        {
            ReflectionUtils.invokeMethod(this.delegate, releaseInstanceMethod, Void.class, true, constraintValidator);
        }
    }

    private synchronized void lazyInit()
    {
        if (releaseInstanceMethodFound != null)
        {
            return;
        }

        Class<?> currentClass = delegate.getClass();
        while (currentClass != null && !Object.class.getName().equals(currentClass.getName()))
        {
            for (Method currentMethod : currentClass.getDeclaredMethods())
            {
                if (RELEASE_INSTANCE_METHOD_NAME.equals(currentMethod.getName()) &&
                        currentMethod.getParameterTypes().length == 1 &&
                        currentMethod.getParameterTypes()[0].equals(ConstraintValidator.class))
                {
                    releaseInstanceMethod = currentMethod;
                    releaseInstanceMethodFound = true;
                    return;
                }

            }

            currentClass = currentClass.getSuperclass();
        }

        releaseInstanceMethodFound = false;
    }
}
