/*
 * Copyright (c) 2009, 2021 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     08/01/2012-2.5 Chris Delahunt
//       - 371950: Metadata caching

package org.eclipse.persistence.internal.jpa.deployment;

import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.util.Map;

import jakarta.validation.Validation;
import jakarta.validation.ValidatorFactory;

import org.eclipse.persistence.config.PersistenceUnitProperties;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.exceptions.PersistenceUnitLoadingException;
import org.eclipse.persistence.internal.jpa.metadata.listeners.BeanValidationListener;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.internal.security.PrivilegedClassForName;
import org.eclipse.persistence.internal.sessions.AbstractSession;

/**
 * Responsible for intialializing Bean Validation. The only expected instance of this interface is the inner class.
 * @author Mitesh Meswani
 */
public interface BeanValidationInitializationHelper {
    void bootstrapBeanValidation(Map puProperties, AbstractSession session, ClassLoader appClassLoader);

    class BeanValidationInitializationHelperImpl implements BeanValidationInitializationHelper {

        public BeanValidationInitializationHelperImpl() {
        }

        @Override
        public void bootstrapBeanValidation(Map puProperties, AbstractSession session, ClassLoader appClassLoader) {

            ValidatorFactory validatorFactory = getValidatorFactory(puProperties);

            //Check user/environment has specified the validator factory
            if (validatorFactory != null) {
                // We could obtain a validator factory => Bean Validation API is available at runtime. It is ok to cast now
                ValidatorFactory beanValidatorFactory = validatorFactory;

                Class[] groupPrePersit = translateValidationGroups(
                        (String) puProperties.get(PersistenceUnitProperties.VALIDATION_GROUP_PRE_PERSIST), appClassLoader) ;
                Class[] groupPreUpdate = translateValidationGroups(
                        (String) puProperties.get(PersistenceUnitProperties.VALIDATION_GROUP_PRE_UPDATE), appClassLoader);
                Class[] groupPreRemove = translateValidationGroups(
                        (String) puProperties.get(PersistenceUnitProperties.VALIDATION_GROUP_PRE_REMOVE), appClassLoader);

                BeanValidationListener validationListener =
                        new BeanValidationListener(beanValidatorFactory, groupPrePersit, groupPreUpdate, groupPreRemove);
                //Install BeanValidationListener on the desc
                for (ClassDescriptor descriptor : session.getProject().getOrderedDescriptors()) {
                    if (descriptor.isDescriptorTypeNormal()) {
                        //add only to entities
                        descriptor.getEventManager().addInternalListener(validationListener);
                    }
                }
            }
        }

        /**
         * INTERNAL:
         * @param puProperties merged properties for this persitence unit
         * @return ValidatorFactory instance to be used for this persistence unit.
         */
        private ValidatorFactory getValidatorFactory(Map puProperties) {
            ValidatorFactory validatorFactory = (ValidatorFactory)puProperties.get(PersistenceUnitProperties.VALIDATOR_FACTORY);

            if (validatorFactory == null) {
                validatorFactory = Validation.buildDefaultValidatorFactory();
            }
            return validatorFactory;
        }


        /**
         * INTERNAL:
         * translate validation group specified as fully qualifed class names deliminated by ',' into Class[]
         * @param validationGroups Array of "," deliminated fully qualified class names
         * @param appClassLoader The classloader for application
         * @return Array of classes corresponding to classnames in given <code>validationGroups</code>.
         *         <code>null</code> if given <code>validationGroups</code> is null or empty
         */
        private Class[] translateValidationGroups(String validationGroups, ClassLoader appClassLoader) {
            Class[] validationGroupsClasses = null;
            if(validationGroups != null && validationGroups.length() != 0 ) {
                String[] validationGroupClassNames = validationGroups.split(",");
                validationGroupsClasses = new Class[validationGroupClassNames.length];
                for(int i = 0; i < validationGroupClassNames.length; i++) {
                    String validationGroupClassName = validationGroupClassNames[i];
                    try {
                        validationGroupsClasses[i] = loadClass(validationGroupClassName, appClassLoader);
                    } catch (Exception e) {
                        throw PersistenceUnitLoadingException.exceptionLoadingClassWhileInitializingValidationGroups(validationGroupClassName, e);
                    }
                }
            }
            return validationGroupsClasses;
        }

        /**
         * Internal:
         * Helper to load class.
         * Please do not make this method protected or public else it would expose a security hole that would
         * allow malicious code to use this method to load any class without security permission
         * @param className Fully qualified class name
         * @param classLoader ClassLoader to be used for loading the class
         * @return Loaded Class
         */
        private Class loadClass(String className, ClassLoader classLoader) throws PrivilegedActionException, ClassNotFoundException {
            Class loadedClass = null;
            if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()) {
                loadedClass = AccessController.doPrivileged(
                        new PrivilegedClassForName<>(className, true, classLoader));
            } else {
                loadedClass = PrivilegedAccessHelper.getClassForName(className, true, classLoader);
            }
            return loadedClass;
        }
    }
}
