/*
 * Copyright (c) 2015, 2020 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.
     * @throws BeanValidationException {@link BeanValidationException#constraintViolation}
     */
    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 + "\".";
        }
    }
}
