/*
 * Copyright (c) 2015, 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:
//     Marcel Valovy - 2.6 - initial implementation
package org.eclipse.persistence.jaxb;

import org.eclipse.persistence.exceptions.BeanValidationException;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.jaxb.xmlmodel.XmlBindings;

import jakarta.validation.ConstraintViolation;
import jakarta.validation.ConstraintViolationException;
import jakarta.validation.Path;
import jakarta.validation.Validation;
import jakarta.validation.ValidationException;
import jakarta.validation.Validator;
import jakarta.validation.ValidatorFactory;
import jakarta.validation.groups.Default;
import java.security.AccessController;
import java.security.CodeSource;
import java.security.PrivilegedAction;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Set;
import java.util.concurrent.locks.ReentrantLock;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * INTERNAL:
 *
 * JAXB Bean Validator. Serves three purposes:
 *  1. Determines if the validation callback should take place on the (un)marshal call.
 *  2. Processes the validation.
 *  3. Stores the constraintViolations from the last validation call.
 *
 * @author Marcel Valovy - marcel.valovy@oracle.com
 * @since 2.6
 */
class JAXBBeanValidator {

    private static Logger logger =
            Logger.getLogger(JAXBBeanValidator.class.getName());

    /**
     * Represents the Default validation group. Storing it in constant saves resources.
     */
    static final Class<?>[] DEFAULT_GROUP_ARRAY = new Class<?>[] { Default.class };

    /**
     * Represents the difference between words 'marshalling' and 'unmarshalling';
     */
    private static final String PREFIX_UNMARSHALLING = "un";

    /**
     * Prevents endless invocation loops between unmarshaller - validator - unmarshaller.
     * Only used / needed in case {@link #noOptimisation} is {@code true}.
     */
    private static final ReentrantLock lock = new ReentrantLock();

    /**
     * Disable optimisations that skip bean validation processes on non-constrained objects.
     */
    private boolean noOptimisation = false;

    /**
     * Stores {@link #PREFIX_UNMARSHALLING} if this instance belongs to
     * {@link org.eclipse.persistence.jaxb.JAXBUnmarshaller}, otherwise stores empty String.
     */
    private final String prefix;

    /**
     * Reference to {@link org.eclipse.persistence.jaxb.JAXBContext}. Allows for callbacks.
     */
    private final JAXBContext context;

    /**
     * Stores the {@link jakarta.validation.Validator} implementation. Once found, the reference is preserved.
     */
    private Validator validator;

    /**
     * Stores constraint violations returned by last call to {@link jakarta.validation.Validator#validate(Object, Class[])}.
     * <p>After each {@link #validate(Object, Class[])} call, the reference is replaced.
     */
    private Set<ConstraintViolation<Object>> constraintViolations = Collections.emptySet();

    /**
     * Computed value saying if the validation can proceed under current conditions, represented by:
     * <blockquote><pre>
     *     - {@link #beanValidationMode}
     *     - {@link jakarta.validation.Validator} implementation present on classpath
     * </pre></blockquote>
     * <p>
     * Value is recomputed only on {@link #changeInternalState()} call.
     */
    private boolean canValidate;

    /**
     * Represents a state where {@link #beanValidationMode} mode is set to
     * {@link org.eclipse.persistence.jaxb.BeanValidationMode#AUTO} and BV implementation could not be found.
     */
    private boolean stopSearchingForValidator;

    /**
     * This field will usually be {@code null}. However, user may pass his own instance of
     * {@link jakarta.validation.ValidatorFactory} to
     * {@link #shouldValidate}() method, and it will be assigned to this field.
     * <p>
     * If not null, {@link #validator} field will be assigned only by calling method
     * {@link jakarta.validation.ValidatorFactory#getValidator()} the instance assigned to this field.
     */
    private ValidatorFactory validatorFactory;

    /**
     * Setting initial value to "NONE" will not trigger internalStateChange() when validation is off and save resources.
     */
    private BeanValidationMode beanValidationMode = BeanValidationMode.NONE;

    /**
     * Private constructor. Only to be called by factory methods.
     * @param prefix differentiates between marshaller and unmarshaller during logging
     * @param context jaxb context reference
     */
    private JAXBBeanValidator(String prefix, JAXBContext context) {
        this.prefix = prefix;
        this.context = context;
    }

    /**
     * Factory method.
     * <p>
     * The only difference between this method and {@link #getUnmarshallingBeanValidator} is not having
     * {@link #PREFIX_UNMARSHALLING} in String messages constructed for exceptions.
     *
     * @param context jaxb context reference
     * @return
     *          a new instance of {@link JAXBBeanValidator}.
     */
    static JAXBBeanValidator getMarshallingBeanValidator(JAXBContext context){
        return new JAXBBeanValidator("", context);
    }

    /**
     * Factory method.
     * <p>
     * The only difference between this method and {@link #getMarshallingBeanValidator} is having
     * {@link #PREFIX_UNMARSHALLING} in String messages constructed for exceptions.
     *
     * @param context jaxb context reference
     * @return
     *          a new instance of {@link JAXBBeanValidator}.
     */
    static JAXBBeanValidator getUnmarshallingBeanValidator(JAXBContext context){
        return new JAXBBeanValidator(PREFIX_UNMARSHALLING, context);
    }

    /**
     * PUBLIC:
     *
     * First, if validation has not been turned off before, check if passed value is constrained.
     *
     * Second, depending on Bean Validation Mode, either returns false or tries to initialize Validator:
     *  - AUTO tries to initialize Validator:
     *          returns true if succeeds, else false.
     *  - CALLBACK tries to initialize Validator:
     *          returns true if succeeds, else throws {@link BeanValidationException#providerNotFound}.
     *  - NONE returns false;
     *
     * BeanValidationMode is fetched from (un)marshaller upon each call.
     * If change in mode is detected, the internal state of the JAXBBeanValidator will be switched.
     *
     * Third, analyses the value and determines whether validation may be skipped.
     *
     * @param beanValidationMode Bean validation mode - allowed values AUTO, CALLBACK, NONE.
     * @param value validated object. It is passed because validation on some objects may be skipped,
     *              e.g. non-constrained objects (like XmlBindings).
     * @param preferredValidatorFactory Must be {@link ValidatorFactory} or null. Will use this factory as the
     *                                  preferred provider; if null, will use javax defaults.
     * @param noOptimisation if true, bean validation optimisations that skip non-constrained objects will not be
     *                       performed
     * @return
     *          true if should proceed with validation, else false.
     * @throws BeanValidationException
     *  {@link BeanValidationException#illegalValidationMode} or {@link BeanValidationException#providerNotFound}.
     * @since 2.6
     */
    boolean shouldValidate (Object value, BeanValidationMode beanValidationMode,
                            Object preferredValidatorFactory,
                            boolean noOptimisation) throws BeanValidationException {

        if (isValidationEffectivelyOff(beanValidationMode)) return false;

        this.noOptimisation = noOptimisation;

        if (!isConstrainedObject(value)) return false;

        /* Mode or validator factory was changed externally (or it's the first time this method is called). */
        if (this.beanValidationMode != beanValidationMode || this.validatorFactory != preferredValidatorFactory) {
            this.beanValidationMode = beanValidationMode;
            this.validatorFactory = (ValidatorFactory)preferredValidatorFactory;
            changeInternalState();
        }

        /* Is Validation implementation ready to validate. */
        return canValidate;
    }

    /**
     * Check if validation is effectively off, i.e. it was previously attempted to turn it on, but that failed.
     * @param beanValidationMode user passed beanValidationMode
     * @return true if validation is effectively off
     */
    private boolean isValidationEffectivelyOff(BeanValidationMode beanValidationMode) {
        return !  ((beanValidationMode == BeanValidationMode.AUTO && canValidate) /* most common case */
                || (beanValidationMode == BeanValidationMode.CALLBACK)
                /* beanValidationMode is AUTO but canValidate is yet to be resolved */
                || (beanValidationMode != BeanValidationMode.NONE && beanValidationMode != this.beanValidationMode)
        );
    }

    /**
     * Check if object contains any bean validation constraints or custom validation constraints.
     * @param value object
     * @return true if the object is not null and is constrained
     */
    private boolean isConstrainedObject(Object value) {
        /* Json is allowed to pass a null root object. Avoid NPE & speed things up. */
        if (value == null) return false;

        if (noOptimisation) {
            /* Stops the endless invocation loop which may occur when calling
             * Validation#buildDefaultValidatorFactory in a case when the user sets
             * custom validation configuration through "validation.xml" file and
             * the validation implementation tries to unmarshal the file with MOXy. */
            if (lock.isHeldByCurrentThread()) return false;

            /* Do not validate XmlBindings. */
            return !(value instanceof XmlBindings);
        }

        /* Ensure that the class contains BV annotations. If not, skip validation & speed things up.
         * note: This also effectively skips XmlBindings. */
        return context.getBeanValidationHelper().isConstrained(value.getClass());
    }

    /**
     * INTERNAL:
     *
     * Validates the value, as per BV spec.
     * Stores the result of validation in {@link #constraintViolations}.
     *
     * @param value Object to be validated.
     * @param groups Target groups as per BV spec. If null {@link #DEFAULT_GROUP_ARRAY} is used.
     */
    void validate(Object value, Class<?>... groups) throws BeanValidationException {
        Class<?>[] grp = groups;
        if (grp == null || grp.length == 0) {
            grp = DEFAULT_GROUP_ARRAY;
        }
        constraintViolations = validator.validate(value, grp);
        if (!constraintViolations.isEmpty())
            throw buildConstraintViolationException();
    }

    /**
     * @return constraintViolations from the last {@link #validate} call.
     */
    Set<ConstraintViolationWrapper<Object>> getConstraintViolations() {
        Set<ConstraintViolationWrapper<Object>> result = new HashSet<>(constraintViolations.size());
        for (ConstraintViolation cv : constraintViolations) {
            result.add(new ConstraintViolationWrapper<>(cv));
        }
        return result;
    }

    /**
     * INTERNAL:
     *
     * Puts variables to states which conform to the internal state machine.
     *
     * Internal states:
     *  Mode/Field Value          | NONE        | AUTO         | CALLBACK
     *  --------------------------|-------------|--------------|--------------
     *  canValidate               | false       | true/false   | true/false
     *  stopSearchingForValidator | false       | true/false   | false
     *  constraintViolations      | EmptySet    | n/a          | n/a
     *
     *  n/a ... value is not altered.
     *
     * @throws BeanValidationException illegalValidationMode or providerNotFound
     */
    private void changeInternalState() throws BeanValidationException {
        stopSearchingForValidator = false; // Reset the switch.
        switch (beanValidationMode) {
        case NONE:
            canValidate = false;
            constraintViolations = Collections.emptySet(); // Clear the reference from previous (un)marshal calls.
            break;
        case CALLBACK:
        case AUTO:
            canValidate = initValidator();
            break;
        default:
            throw BeanValidationException.illegalValidationMode(prefix, beanValidationMode.toString());
        }
    }

    /**
     * PUBLIC:
     *
     * Initializes validator if not already initialized.
     * If mode is BeanValidationMode.AUTO, then after an unsuccessful try to
     * initialize a Validator, property {@code stopSearchingForValidator} will be set to true.
     *
     * NOTE: Property {@code stopSearchingForValidator} can be reset only by triggering
     * {@link #changeInternalState}.
     *
     * @return {@code true} if validator initialization succeeded, otherwise {@code false}.
     * @throws BeanValidationException
     *              throws {@link org.eclipse.persistence.exceptions.BeanValidationException#PROVIDER_NOT_FOUND}
     */
    private boolean initValidator() throws BeanValidationException {
        if (validator == null && !stopSearchingForValidator){
            try {
                ValidatorFactory factory = getValidatorFactory();
                validator = factory.getValidator();
                printValidatorInfo();
            } catch (ValidationException ve) {
                if (beanValidationMode == BeanValidationMode.CALLBACK){
                    /* The following line ensures that changeInternalState() will be the
                     triggered on next (un)marshalling trials if mode is still CALLBACK.
                      That will ensure searching for Validator implementation again. */
                    beanValidationMode = BeanValidationMode.AUTO;
                    throw BeanValidationException.providerNotFound(prefix, ve);
                } else { // mode AUTO
                    stopSearchingForValidator = true; // Will not try to initialize validator on next tries.
                }
            }
        }
        return validator != null;
    }

    /**
     * INTERNAL:
     *
     * @return Preferred ValidatorFactory if set, else {@link Validation#buildDefaultValidatorFactory()}.
     */
    private ValidatorFactory getValidatorFactory() {
        if (validatorFactory != null) {
            return validatorFactory;
        }

        if (noOptimisation) {
            lock.lock();
            try {
                return Validation.buildDefaultValidatorFactory();
            } finally {
                lock.unlock();
            }
        }

        return Validation.buildDefaultValidatorFactory();
    }

    /**
     * INTERNAL:
     *
     * Builds ConstraintViolationException with constraintViolations, but no message.
     * Builds BeanValidationException with fully descriptive message, containing
     * the ConstraintViolationException.
     *
     * @return BeanValidationException, containing ConstraintViolationException.
     */
    @SuppressWarnings({"RedundantCast", "unchecked"})
    private BeanValidationException buildConstraintViolationException() {
        ConstraintViolationException cve = new ConstraintViolationException(
                /* Do not remove the cast. */ constraintViolations);
        return BeanValidationException.constraintViolation(createConstraintViolationExceptionArgs(), cve);
    }

    /**
     * INTERNAL:
     * Builds an Object array containing args for ConstraintViolationException constructor.
     *
     * @return  [0] - prefix,
     *          [1] - rootBean (on what object the validation failed),
     *          [2] - linkedList of violatedConstraints, with overriden toString() for better formatting.
     */
    private Object[] createConstraintViolationExceptionArgs() {
        Object[] args = new Object[3];
        Iterator<? extends ConstraintViolation<?>> iterator = constraintViolations.iterator();
        assert iterator.hasNext(); // this method is to be called only if constraints violations are not empty
        ConstraintViolation<?> cv = iterator.next();
        Collection<ConstraintViolationInfo> violatedConstraints = new LinkedList<ConstraintViolationInfo>(){
            @Override
            public String toString() {
                Iterator<ConstraintViolationInfo> it = iterator();
                StringBuilder sb = new StringBuilder();
                while (it.hasNext())
                    sb.append("\n-->").append(it.next().toString());
                return sb.toString();
            }
        };
        args[0] = prefix;
        Object bean = cv.getRootBean();
        // NOTE:
        // 1. Do not use bean.toString(), it could leak secure information.
        // 2. And use identityHashCode, for these reasons:
        //      - prevents NPE which could be caused by a poorly implemented hashCode
        //      - serves as a better mean of identification of the bean.
        args[1] = bean.getClass().toString().substring("class ".length())
                + "@" + Integer.toHexString(System.identityHashCode(bean));
        args[2] = violatedConstraints;
        for (;;) {
            violatedConstraints.add(new ConstraintViolationInfo(cv.getMessage(), cv.getPropertyPath()));
            if (iterator.hasNext()) cv = iterator.next();
            else break;
        }
        return args;
    }

    /**
     * Logs the name of underlying validation impl jar used. Only logs once per context to avoid log cluttering.
     * To be called after successful assignment of validator.
     */
    private void printValidatorInfo() {
        if (!context.getHasLoggedValidatorInfo().getAndSet(true)) {
            CodeSource validationImplJar = getValidatorCodeSource();
            if (logger.isLoggable(Level.FINE)) {
                logger.fine("EclipseLink is using " + validationImplJar + " as BeanValidation implementation.");
            }
        }
    }

    /**
     * INTERNAL:
     * Retrieves code source of validator.
     *
     * @return Validator code source. May be null.
     */
    private CodeSource getValidatorCodeSource() {
        if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()) {
            return AccessController.doPrivileged(new PrivilegedAction<CodeSource>() {
                @Override
                public CodeSource run() {
                    return validator.getClass().getProtectionDomain().getCodeSource();
                }
            });
        } else {
            return validator.getClass().getProtectionDomain().getCodeSource();
        }
    }

    /**
     * INTERNAL:
     *
     * Value Object class that provides adequate toString() method which describes
     * on which field a Validation Constraint was violated and includes it's violationDescription.
     */
    private static class ConstraintViolationInfo {
        /**
         * Description of constraint violation.
         */
        private final String violationDescription;

        /**
         * Path to element on which the constraint violation occurred.
         */
        private final Path propertyPath;

        /**
         * Private constructor. Only to be used from within {@link org.eclipse.persistence.jaxb.JAXBBeanValidator}.
         *
         * @param message description of constraint violation
         * @param propertyPath path to element on which the constraint violation occurred
         */
        private ConstraintViolationInfo(String message, Path propertyPath){
            this.violationDescription = message;
            this.propertyPath = propertyPath;
        }

        @Override
        public String toString() {
            return "Violated constraint on property " + propertyPath + ": \"" + violationDescription + "\".";
        }
    }
}
