/*
 * Copyright (c) 2011, 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:
//     James Sutherland (Oracle) - initial API and implementation
//      //     30/05/2012-2.4 Guy Pelletier
//       - 354678: Temp classloader is still being used during metadata processing
package org.eclipse.persistence.descriptors.partitioning;

import java.lang.reflect.Constructor;
import java.security.AccessController;
import java.security.PrivilegedActionException;

import org.eclipse.persistence.exceptions.ValidationException;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.internal.security.PrivilegedClassForName;
import org.eclipse.persistence.internal.security.PrivilegedGetConstructorFor;
import org.eclipse.persistence.internal.security.PrivilegedInvokeConstructor;

/**
 * PUBLIC:
 * Represent a specific range partition.
 * Values {@literal >=} startValue and {@literal <=} endValue will be routed to the connection pool.
 * @author James Sutherland
 * @since EclipseLink 2.2
 */
public class RangePartition  {
    protected String endValueName;
    protected String startValueName;
    protected String partitionValueTypeName;
    protected String connectionPool;

    protected Class partitionValueType;
    protected Comparable startValue;
    protected Comparable endValue;

    public RangePartition() {}

    /**
     * INTERNAL:
     * COnstructor used from metadata processing to avoid classloader
     * dependencies. Class names are converted/initialized in the
     * convertClassNamesToClasses method.
     */
    public RangePartition(String connectionPool, String partitionValueTypeName, String startValueName, String endValueName) {
        this.connectionPool = connectionPool;
        this.endValue = null;
        this.endValueName = endValueName;
        this.startValue = null;
        this.startValueName = startValueName;
        this.partitionValueTypeName = partitionValueTypeName;
    }

    /**
     * PUBLIC:
     * Create the partition for the connectionPool and start/end values.
     */
    public RangePartition(String connectionPool, Comparable startValue, Comparable endValue) {
        this.connectionPool = connectionPool;
        this.startValue = startValue;
        this.endValue = endValue;
    }

    /**
     * INTERNAL:
     * Convert all the class-name-based settings to actual class-based settings.
     * This method is used when converting a project that has been built with
     * class names to a project with classes.
     */
    public void convertClassNamesToClasses(ClassLoader classLoader) {
        if (partitionValueType == null && partitionValueTypeName != null) {
            try {
                if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
                    try {
                        partitionValueType = AccessController.doPrivileged(new PrivilegedClassForName<>(partitionValueTypeName, true, classLoader));
                    } catch (PrivilegedActionException e) {
                        throw ValidationException.classNotFoundWhileConvertingClassNames(partitionValueTypeName, e.getException());
                    }
                } else {
                    partitionValueType = org.eclipse.persistence.internal.security.PrivilegedAccessHelper.getClassForName(partitionValueTypeName, true, classLoader);
                }
            } catch (Exception exception) {
                throw ValidationException.classNotFoundWhileConvertingClassNames(partitionValueTypeName, exception);
            }
        }

        // Once we know we have a partition value type we can convert our partition ranges.
        if (partitionValueType != null) {
            if (startValueName != null) {
                startValue = (Comparable) initObject(partitionValueType, startValueName);
            }

            if (endValueName != null) {
                endValue = (Comparable) initObject(partitionValueType, endValueName);
            }
        }
    }

    /**
     * PUBLIC:
     * Return the range start value.  Values greater or equal to this value are part of this partition.
     */
    public Comparable getStartValue() {
        return startValue;
    }

    /**
     * INTERNAL:
     * TODO: clean up the exception handling.
     */
    @SuppressWarnings({"unchecked"})
    protected <T> T initObject(Class<T> type, String value) {
        if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()) {
            try {
                Constructor<T> constructor = AccessController.doPrivileged(new PrivilegedGetConstructorFor<>(type, new Class[] {String.class}, false));
                return AccessController.doPrivileged(new PrivilegedInvokeConstructor<>(constructor, new Object[] {value}));
            } catch (PrivilegedActionException exception) {
                //throwInitObjectException(exception, type, value, isData);
            }
        } else {
            try {
                Constructor<T> constructor = PrivilegedAccessHelper.getConstructorFor(type, new Class[] {String.class}, false);
                return PrivilegedAccessHelper.invokeConstructor(constructor, new Object[] {value});
            } catch (Exception exception) {
                //throwInitObjectException(exception, type, value, isData);
            }
        }

        return (T) value;
    }

    /**
     * PUBLIC:
     * Set the range start value.  Values greater or equal to this value are part of this partition.
     */
    public void setStartValue(Comparable startValue) {
        this.startValue = startValue;
    }

    /**
     * PUBLIC:
     * Return the range end value.  Values less than or equal this value are part of this partition.
     */
    public Comparable getEndValue() {
        return endValue;
    }

    /**
     * PUBLIC:
     * Set the range end value.  Values less than or equal this value are part of this partition.
     */
    public void setEndValue(Comparable endValue) {
        this.endValue = endValue;
    }

    /**
     * PUBLIC:
     * Return the connection pool to use for this partition.
     */
    public String getConnectionPool() {
        return connectionPool;
    }

    /**
     * PUBLIC:
     * Return the connection pool to use for this partition.
     */
    public void setConnectionPool(String connectionPool) {
        this.connectionPool = connectionPool;
    }

    /**
     * INTERNAL:
     * Return if the value is in the partitions range.
     */
    public boolean isInRange(Object value) {
        if ((this.startValue != null) && (this.startValue.compareTo(value) > 0)) {
            return false;
        }
        if ((this.endValue != null) && (this.endValue.compareTo(value) < 0)) {
            return false;
        }
        return true;
    }

}
